Matrix.cpp revision 9d5316e3f56d138504565ff311145ac01621dff4
108ae317c21ec3086b5017672bba87420cc38a407Romain Guy/* 208ae317c21ec3086b5017672bba87420cc38a407Romain Guy * Copyright (C) 2010 The Android Open Source Project 308ae317c21ec3086b5017672bba87420cc38a407Romain Guy * 408ae317c21ec3086b5017672bba87420cc38a407Romain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 508ae317c21ec3086b5017672bba87420cc38a407Romain Guy * you may not use this file except in compliance with the License. 608ae317c21ec3086b5017672bba87420cc38a407Romain Guy * You may obtain a copy of the License at 708ae317c21ec3086b5017672bba87420cc38a407Romain Guy * 808ae317c21ec3086b5017672bba87420cc38a407Romain Guy * http://www.apache.org/licenses/LICENSE-2.0 908ae317c21ec3086b5017672bba87420cc38a407Romain Guy * 1008ae317c21ec3086b5017672bba87420cc38a407Romain Guy * Unless required by applicable law or agreed to in writing, software 1108ae317c21ec3086b5017672bba87420cc38a407Romain Guy * distributed under the License is distributed on an "AS IS" BASIS, 1208ae317c21ec3086b5017672bba87420cc38a407Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1308ae317c21ec3086b5017672bba87420cc38a407Romain Guy * See the License for the specific language governing permissions and 1408ae317c21ec3086b5017672bba87420cc38a407Romain Guy * limitations under the License. 1508ae317c21ec3086b5017672bba87420cc38a407Romain Guy */ 1608ae317c21ec3086b5017672bba87420cc38a407Romain Guy 179d5316e3f56d138504565ff311145ac01621dff4Romain Guy#define LOG_TAG "Matrix" 1808ae317c21ec3086b5017672bba87420cc38a407Romain Guy 1908ae317c21ec3086b5017672bba87420cc38a407Romain Guy#include <math.h> 2008ae317c21ec3086b5017672bba87420cc38a407Romain Guy#include <stdlib.h> 213e168335b3422008908ac6973bb36078fd979f35Romain Guy#include <string.h> 2208ae317c21ec3086b5017672bba87420cc38a407Romain Guy 2308ae317c21ec3086b5017672bba87420cc38a407Romain Guy#include <utils/Log.h> 2408ae317c21ec3086b5017672bba87420cc38a407Romain Guy 25f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy#include <SkMatrix.h> 26f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 2785bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy#include "Matrix.h" 2808ae317c21ec3086b5017672bba87420cc38a407Romain Guy 2908ae317c21ec3086b5017672bba87420cc38a407Romain Guynamespace android { 309d5316e3f56d138504565ff311145ac01621dff4Romain Guynamespace uirenderer { 3108ae317c21ec3086b5017672bba87420cc38a407Romain Guy 3208ae317c21ec3086b5017672bba87420cc38a407Romain Guyvoid Matrix4::loadIdentity() { 33f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[0] = 1.0f; 34f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[1] = 0.0f; 35f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[2] = 0.0f; 36f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[3] = 0.0f; 37f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 38f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[4] = 0.0f; 39f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[5] = 1.0f; 40f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[6] = 0.0f; 41f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[7] = 0.0f; 42f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 43f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[8] = 0.0f; 44f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[9] = 0.0f; 45f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[10] = 1.0f; 46f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[11] = 0.0f; 47f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 48f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[12] = 0.0f; 49f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[13] = 0.0f; 50f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[14] = 0.0f; 51f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[15] = 1.0f; 5208ae317c21ec3086b5017672bba87420cc38a407Romain Guy} 5308ae317c21ec3086b5017672bba87420cc38a407Romain Guy 5408ae317c21ec3086b5017672bba87420cc38a407Romain Guyvoid Matrix4::load(const float* v) { 5508ae317c21ec3086b5017672bba87420cc38a407Romain Guy memcpy(mMat, v, sizeof(mMat)); 5608ae317c21ec3086b5017672bba87420cc38a407Romain Guy} 5708ae317c21ec3086b5017672bba87420cc38a407Romain Guy 5808ae317c21ec3086b5017672bba87420cc38a407Romain Guyvoid Matrix4::load(const Matrix4& v) { 5908ae317c21ec3086b5017672bba87420cc38a407Romain Guy memcpy(mMat, v.mMat, sizeof(mMat)); 6008ae317c21ec3086b5017672bba87420cc38a407Romain Guy} 6108ae317c21ec3086b5017672bba87420cc38a407Romain Guy 62f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guyvoid Matrix4::load(const SkMatrix& v) { 63f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy memset(mMat, 0, sizeof(mMat)); 64f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 65f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[0] = v[SkMatrix::kMScaleX]; 66f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[4] = v[SkMatrix::kMSkewX]; 67f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[12] = v[SkMatrix::kMTransX]; 68f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 69f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[1] = v[SkMatrix::kMSkewY]; 70f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[5] = v[SkMatrix::kMScaleY]; 71f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[13] = v[SkMatrix::kMTransY]; 72f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 73f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[3] = v[SkMatrix::kMPersp0]; 74f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[7] = v[SkMatrix::kMPersp1]; 75f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[15] = v[SkMatrix::kMPersp2]; 76f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 77f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[10] = 1.0f; 78f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy} 79f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 80f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guyvoid Matrix4::copyTo(SkMatrix& v) const { 81f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy v.reset(); 82f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 83f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy v.set(SkMatrix::kMScaleX, mMat[0]); 84f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy v.set(SkMatrix::kMSkewX, mMat[4]); 85f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy v.set(SkMatrix::kMTransX, mMat[12]); 86f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 87f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy v.set(SkMatrix::kMSkewY, mMat[1]); 88f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy v.set(SkMatrix::kMScaleY, mMat[5]); 89f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy v.set(SkMatrix::kMTransY, mMat[13]); 90f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 91f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy v.set(SkMatrix::kMPersp0, mMat[3]); 92f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy v.set(SkMatrix::kMPersp1, mMat[7]); 93f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy v.set(SkMatrix::kMPersp2, mMat[15]); 94f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy} 95f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 9608ae317c21ec3086b5017672bba87420cc38a407Romain Guyvoid Matrix4::copyTo(float* v) const { 9708ae317c21ec3086b5017672bba87420cc38a407Romain Guy memcpy(v, mMat, sizeof(mMat)); 9808ae317c21ec3086b5017672bba87420cc38a407Romain Guy} 9908ae317c21ec3086b5017672bba87420cc38a407Romain Guy 10008ae317c21ec3086b5017672bba87420cc38a407Romain Guyvoid Matrix4::loadTranslate(float x, float y, float z) { 10108ae317c21ec3086b5017672bba87420cc38a407Romain Guy loadIdentity(); 10208ae317c21ec3086b5017672bba87420cc38a407Romain Guy mMat[12] = x; 10308ae317c21ec3086b5017672bba87420cc38a407Romain Guy mMat[13] = y; 10408ae317c21ec3086b5017672bba87420cc38a407Romain Guy mMat[14] = z; 10508ae317c21ec3086b5017672bba87420cc38a407Romain Guy} 10608ae317c21ec3086b5017672bba87420cc38a407Romain Guy 10708ae317c21ec3086b5017672bba87420cc38a407Romain Guyvoid Matrix4::loadScale(float sx, float sy, float sz) { 10808ae317c21ec3086b5017672bba87420cc38a407Romain Guy loadIdentity(); 10908ae317c21ec3086b5017672bba87420cc38a407Romain Guy mMat[0] = sx; 11008ae317c21ec3086b5017672bba87420cc38a407Romain Guy mMat[5] = sy; 11108ae317c21ec3086b5017672bba87420cc38a407Romain Guy mMat[10] = sz; 11208ae317c21ec3086b5017672bba87420cc38a407Romain Guy} 11308ae317c21ec3086b5017672bba87420cc38a407Romain Guy 11408ae317c21ec3086b5017672bba87420cc38a407Romain Guyvoid Matrix4::loadRotate(float angle, float x, float y, float z) { 115f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[3] = 0.0f; 116f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[7] = 0.0f; 117f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[11] = 0.0f; 118f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[12] = 0.0f; 119f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[13] = 0.0f; 120f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[14] = 0.0f; 121f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[15] = 1.0f; 12208ae317c21ec3086b5017672bba87420cc38a407Romain Guy 12308ae317c21ec3086b5017672bba87420cc38a407Romain Guy angle *= float(M_PI / 180.0f); 12408ae317c21ec3086b5017672bba87420cc38a407Romain Guy float c = cosf(angle); 12508ae317c21ec3086b5017672bba87420cc38a407Romain Guy float s = sinf(angle); 12608ae317c21ec3086b5017672bba87420cc38a407Romain Guy 12708ae317c21ec3086b5017672bba87420cc38a407Romain Guy const float length = sqrtf(x * x + y * y + z * z); 12808ae317c21ec3086b5017672bba87420cc38a407Romain Guy const float nc = 1.0f - c; 12908ae317c21ec3086b5017672bba87420cc38a407Romain Guy const float xy = x * y; 13008ae317c21ec3086b5017672bba87420cc38a407Romain Guy const float yz = y * z; 13108ae317c21ec3086b5017672bba87420cc38a407Romain Guy const float zx = z * x; 13208ae317c21ec3086b5017672bba87420cc38a407Romain Guy const float xs = x * s; 13308ae317c21ec3086b5017672bba87420cc38a407Romain Guy const float ys = y * s; 13408ae317c21ec3086b5017672bba87420cc38a407Romain Guy const float zs = z * s; 13508ae317c21ec3086b5017672bba87420cc38a407Romain Guy 13608ae317c21ec3086b5017672bba87420cc38a407Romain Guy mMat[0] = x * x * nc + c; 13708ae317c21ec3086b5017672bba87420cc38a407Romain Guy mMat[4] = xy * nc - zs; 13808ae317c21ec3086b5017672bba87420cc38a407Romain Guy mMat[8] = zx * nc + ys; 13908ae317c21ec3086b5017672bba87420cc38a407Romain Guy mMat[1] = xy * nc + zs; 14008ae317c21ec3086b5017672bba87420cc38a407Romain Guy mMat[5] = y * y * nc + c; 14108ae317c21ec3086b5017672bba87420cc38a407Romain Guy mMat[9] = yz * nc - xs; 14208ae317c21ec3086b5017672bba87420cc38a407Romain Guy mMat[2] = zx * nc - ys; 14308ae317c21ec3086b5017672bba87420cc38a407Romain Guy mMat[6] = yz * nc + xs; 14408ae317c21ec3086b5017672bba87420cc38a407Romain Guy mMat[10] = z * z * nc + c; 14508ae317c21ec3086b5017672bba87420cc38a407Romain Guy} 14608ae317c21ec3086b5017672bba87420cc38a407Romain Guy 14708ae317c21ec3086b5017672bba87420cc38a407Romain Guyvoid Matrix4::loadMultiply(const Matrix4& u, const Matrix4& v) { 14808ae317c21ec3086b5017672bba87420cc38a407Romain Guy for (int i = 0 ; i < 4 ; i++) { 14908ae317c21ec3086b5017672bba87420cc38a407Romain Guy float x = 0; 15008ae317c21ec3086b5017672bba87420cc38a407Romain Guy float y = 0; 15108ae317c21ec3086b5017672bba87420cc38a407Romain Guy float z = 0; 15208ae317c21ec3086b5017672bba87420cc38a407Romain Guy float w = 0; 15308ae317c21ec3086b5017672bba87420cc38a407Romain Guy 15408ae317c21ec3086b5017672bba87420cc38a407Romain Guy for (int j = 0 ; j < 4 ; j++) { 15508ae317c21ec3086b5017672bba87420cc38a407Romain Guy const float e = v.get(i,j); 15608ae317c21ec3086b5017672bba87420cc38a407Romain Guy x += u.get(j, 0) * e; 15708ae317c21ec3086b5017672bba87420cc38a407Romain Guy y += u.get(j, 1) * e; 15808ae317c21ec3086b5017672bba87420cc38a407Romain Guy z += u.get(j, 2) * e; 15908ae317c21ec3086b5017672bba87420cc38a407Romain Guy w += u.get(j, 3) * e; 16008ae317c21ec3086b5017672bba87420cc38a407Romain Guy } 16108ae317c21ec3086b5017672bba87420cc38a407Romain Guy 16208ae317c21ec3086b5017672bba87420cc38a407Romain Guy set(i, 0, x); 16308ae317c21ec3086b5017672bba87420cc38a407Romain Guy set(i, 1, y); 16408ae317c21ec3086b5017672bba87420cc38a407Romain Guy set(i, 2, z); 16508ae317c21ec3086b5017672bba87420cc38a407Romain Guy set(i, 3, w); 16608ae317c21ec3086b5017672bba87420cc38a407Romain Guy } 16708ae317c21ec3086b5017672bba87420cc38a407Romain Guy} 16808ae317c21ec3086b5017672bba87420cc38a407Romain Guy 16908ae317c21ec3086b5017672bba87420cc38a407Romain Guyvoid Matrix4::loadOrtho(float left, float right, float bottom, float top, float near, float far) { 17008ae317c21ec3086b5017672bba87420cc38a407Romain Guy loadIdentity(); 171f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[0] = 2.0f / (right - left); 172f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[5] = 2.0f / (top - bottom); 173f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mMat[10] = -2.0f / (far - near); 17408ae317c21ec3086b5017672bba87420cc38a407Romain Guy mMat[12] = -(right + left) / (right - left); 17508ae317c21ec3086b5017672bba87420cc38a407Romain Guy mMat[13] = -(top + bottom) / (top - bottom); 17608ae317c21ec3086b5017672bba87420cc38a407Romain Guy mMat[14] = -(far + near) / (far - near); 17708ae317c21ec3086b5017672bba87420cc38a407Romain Guy} 17808ae317c21ec3086b5017672bba87420cc38a407Romain Guy 1799d5316e3f56d138504565ff311145ac01621dff4Romain Guy#define MUL_ADD_STORE(a, b, c) a = (a) * (b) + (c) 1809d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1819d5316e3f56d138504565ff311145ac01621dff4Romain Guyvoid Matrix4::mapRect(Rect& r) const { 1829d5316e3f56d138504565ff311145ac01621dff4Romain Guy const float sx = mMat[0]; 1839d5316e3f56d138504565ff311145ac01621dff4Romain Guy const float sy = mMat[5]; 1849d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1859d5316e3f56d138504565ff311145ac01621dff4Romain Guy const float tx = mMat[12]; 1869d5316e3f56d138504565ff311145ac01621dff4Romain Guy const float ty = mMat[13]; 1879d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1889d5316e3f56d138504565ff311145ac01621dff4Romain Guy MUL_ADD_STORE(r.left, sx, tx); 1899d5316e3f56d138504565ff311145ac01621dff4Romain Guy MUL_ADD_STORE(r.right, sx, tx); 1909d5316e3f56d138504565ff311145ac01621dff4Romain Guy MUL_ADD_STORE(r.top, sy, ty); 1919d5316e3f56d138504565ff311145ac01621dff4Romain Guy MUL_ADD_STORE(r.bottom, sy, ty); 1929d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 1939d5316e3f56d138504565ff311145ac01621dff4Romain Guy 19408ae317c21ec3086b5017672bba87420cc38a407Romain Guyvoid Matrix4::dump() const { 195bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy LOGD("Matrix4["); 196bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy LOGD(" %f %f %f %f", mMat[0], mMat[4], mMat[ 8], mMat[12]); 197bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy LOGD(" %f %f %f %f", mMat[1], mMat[5], mMat[ 9], mMat[13]); 198bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy LOGD(" %f %f %f %f", mMat[2], mMat[6], mMat[10], mMat[14]); 199bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy LOGD(" %f %f %f %f", mMat[3], mMat[7], mMat[11], mMat[15]); 200bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy LOGD("]"); 20108ae317c21ec3086b5017672bba87420cc38a407Romain Guy} 20208ae317c21ec3086b5017672bba87420cc38a407Romain Guy 2039d5316e3f56d138504565ff311145ac01621dff4Romain Guy}; // namespace uirenderer 2049d5316e3f56d138504565ff311145ac01621dff4Romain Guy}; // namespace android 205