Matrix.java revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.opengl; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Matrix math utilities. These methods operate on OpenGL ES format 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * matrices and vectors stored in float arrays. 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Matrices are 4 x 4 column-vector matrices stored in column-major 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * order: 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * m[offset + 0] m[offset + 4] m[offset + 8] m[offset + 12] 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * m[offset + 1] m[offset + 5] m[offset + 9] m[offset + 13] 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * m[offset + 2] m[offset + 6] m[offset + 10] m[offset + 14] 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * m[offset + 3] m[offset + 7] m[offset + 11] m[offset + 15] 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </pre> 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Vectors are 4 row x 1 column column-vectors stored in order: 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * v[offset + 0] 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * v[offset + 1] 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * v[offset + 2] 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * v[offset + 3] 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </pre> 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Matrix { 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Multiply two 4x4 matrices together and store the result in a third 4x4 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * matrix. In matrix notation: result = lhs x rhs. Due to the way 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * matrix multiplication works, the result matrix will have the same 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * effect as first multiplying by the rhs matrix, then multiplying by 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the lhs matrix. This is the opposite of what you might expect. 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The same float array may be passed for result, lhs, and/or rhs. However, 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the result element values are undefined if the result elements overlap 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * either the lhs or rhs elements. 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param result The float array that holds the result. 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param resultOffset The offset into the result array where the result is 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * stored. 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param lhs The float array that holds the left-hand-side matrix. 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param lhsOffset The offset into the lhs array where the lhs is stored 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rhs The float array that holds the right-hand-side matrix. 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rhsOffset The offset into the rhs array where the rhs is stored. 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalArgumentException if result, lhs, or rhs are null, or if 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * resultOffset + 16 > result.length or lhsOffset + 16 > lhs.length or 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * rhsOffset + 16 > rhs.length. 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static native void multiplyMM(float[] result, int resultOffset, 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] lhs, int lhsOffset, float[] rhs, int rhsOffset); 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Multiply a 4 element vector by a 4x4 matrix and store the result in a 4 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * element column vector. In matrix notation: result = lhs x rhs 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The same float array may be passed for resultVec, lhsMat, and/or rhsVec. 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * However, the resultVec element values are undefined if the resultVec 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * elements overlap either the lhsMat or rhsVec elements. 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param resultVec The float array that holds the result vector. 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param resultVecOffset The offset into the result array where the result 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * vector is stored. 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param lhsMat The float array that holds the left-hand-side matrix. 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param lhsMatOffset The offset into the lhs array where the lhs is stored 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rhsVec The float array that holds the right-hand-side vector. 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rhsVecOffset The offset into the rhs vector where the rhs vector 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is stored. 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalArgumentException if resultVec, lhsMat, 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or rhsVec are null, or if resultVecOffset + 4 > resultVec.length 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or lhsMatOffset + 16 > lhsMat.length or 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * rhsVecOffset + 4 > rhsVec.length. 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static native void multiplyMV(float[] resultVec, 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int resultVecOffset, float[] lhsMat, int lhsMatOffset, 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] rhsVec, int rhsVecOffset); 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Transposes a 4 x 4 matrix. 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mTrans the array that holds the output inverted matrix 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mTransOffset an offset into mInv where the inverted matrix is 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * stored. 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param m the input array 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mOffset an offset into m where the matrix is stored. 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void transposeM(float[] mTrans, int mTransOffset, float[] m, 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mOffset) { 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < 4; i++) { 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mBase = i * 4 + mOffset; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTrans[i + mTransOffset] = m[mBase]; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTrans[i + 4 + mTransOffset] = m[mBase + 1]; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTrans[i + 8 + mTransOffset] = m[mBase + 2]; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTrans[i + 12 + mTransOffset] = m[mBase + 3]; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inverts a 4 x 4 matrix. 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mInv the array that holds the output inverted matrix 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mInvOffset an offset into mInv where the inverted matrix is 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * stored. 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param m the input array 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mOffset an offset into m where the matrix is stored. 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the matrix could be inverted, false if it could not. 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean invertM(float[] mInv, int mInvOffset, float[] m, 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mOffset) { 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Invert a 4 x 4 matrix using Cramer's Rule 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // array of transpose source matrix 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] src = new float[16]; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // transpose matrix 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project transposeM(src, 0, m, mOffset); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // temp array for pairs 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] tmp = new float[12]; 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // calculate pairs for first 8 elements (cofactors) 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp[0] = src[10] * src[15]; 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp[1] = src[11] * src[14]; 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp[2] = src[9] * src[15]; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp[3] = src[11] * src[13]; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp[4] = src[9] * src[14]; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp[5] = src[10] * src[13]; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp[6] = src[8] * src[15]; 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp[7] = src[11] * src[12]; 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp[8] = src[8] * src[14]; 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp[9] = src[10] * src[12]; 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp[10] = src[8] * src[13]; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp[11] = src[9] * src[12]; 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Holds the destination matrix while we're building it up. 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] dst = new float[16]; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // calculate first 8 elements (cofactors) 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[0] = tmp[0] * src[5] + tmp[3] * src[6] + tmp[4] * src[7]; 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[0] -= tmp[1] * src[5] + tmp[2] * src[6] + tmp[5] * src[7]; 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[1] = tmp[1] * src[4] + tmp[6] * src[6] + tmp[9] * src[7]; 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[1] -= tmp[0] * src[4] + tmp[7] * src[6] + tmp[8] * src[7]; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[2] = tmp[2] * src[4] + tmp[7] * src[5] + tmp[10] * src[7]; 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[2] -= tmp[3] * src[4] + tmp[6] * src[5] + tmp[11] * src[7]; 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[3] = tmp[5] * src[4] + tmp[8] * src[5] + tmp[11] * src[6]; 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[3] -= tmp[4] * src[4] + tmp[9] * src[5] + tmp[10] * src[6]; 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[4] = tmp[1] * src[1] + tmp[2] * src[2] + tmp[5] * src[3]; 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[4] -= tmp[0] * src[1] + tmp[3] * src[2] + tmp[4] * src[3]; 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[5] = tmp[0] * src[0] + tmp[7] * src[2] + tmp[8] * src[3]; 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[5] -= tmp[1] * src[0] + tmp[6] * src[2] + tmp[9] * src[3]; 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[6] = tmp[3] * src[0] + tmp[6] * src[1] + tmp[11] * src[3]; 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[6] -= tmp[2] * src[0] + tmp[7] * src[1] + tmp[10] * src[3]; 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[7] = tmp[4] * src[0] + tmp[9] * src[1] + tmp[10] * src[2]; 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[7] -= tmp[5] * src[0] + tmp[8] * src[1] + tmp[11] * src[2]; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // calculate pairs for second 8 elements (cofactors) 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp[0] = src[2] * src[7]; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp[1] = src[3] * src[6]; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp[2] = src[1] * src[7]; 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp[3] = src[3] * src[5]; 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp[4] = src[1] * src[6]; 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp[5] = src[2] * src[5]; 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp[6] = src[0] * src[7]; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp[7] = src[3] * src[4]; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp[8] = src[0] * src[6]; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp[9] = src[2] * src[4]; 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp[10] = src[0] * src[5]; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp[11] = src[1] * src[4]; 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // calculate second 8 elements (cofactors) 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[8] = tmp[0] * src[13] + tmp[3] * src[14] + tmp[4] * src[15]; 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[8] -= tmp[1] * src[13] + tmp[2] * src[14] + tmp[5] * src[15]; 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[9] = tmp[1] * src[12] + tmp[6] * src[14] + tmp[9] * src[15]; 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[9] -= tmp[0] * src[12] + tmp[7] * src[14] + tmp[8] * src[15]; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[10] = tmp[2] * src[12] + tmp[7] * src[13] + tmp[10] * src[15]; 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[10] -= tmp[3] * src[12] + tmp[6] * src[13] + tmp[11] * src[15]; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[11] = tmp[5] * src[12] + tmp[8] * src[13] + tmp[11] * src[14]; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[11] -= tmp[4] * src[12] + tmp[9] * src[13] + tmp[10] * src[14]; 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[12] = tmp[2] * src[10] + tmp[5] * src[11] + tmp[1] * src[9]; 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[12] -= tmp[4] * src[11] + tmp[0] * src[9] + tmp[3] * src[10]; 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[13] = tmp[8] * src[11] + tmp[0] * src[8] + tmp[7] * src[10]; 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[13] -= tmp[6] * src[10] + tmp[9] * src[11] + tmp[1] * src[8]; 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[14] = tmp[6] * src[9] + tmp[11] * src[11] + tmp[3] * src[8]; 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[14] -= tmp[10] * src[11] + tmp[2] * src[8] + tmp[7] * src[9]; 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[15] = tmp[10] * src[10] + tmp[4] * src[8] + tmp[9] * src[9]; 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[15] -= tmp[8] * src[9] + tmp[11] * src[10] + tmp[5] * src[8]; 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // calculate determinant 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float det = 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project src[0] * dst[0] + src[1] * dst[1] + src[2] * dst[2] + src[3] 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * dst[3]; 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (det == 0.0f) { 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // calculate matrix inverse 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project det = 1 / det; 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int j = 0; j < 16; j++) 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mInv[j + mInvOffset] = dst[j] * det; 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Computes an orthographic projection matrix. 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param m returns the result 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mOffset 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param left 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param right 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param bottom 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param top 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param near 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param far 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void orthoM(float[] m, int mOffset, 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float left, float right, float bottom, float top, 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float near, float far) { 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (left == right) { 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("left == right"); 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bottom == top) { 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("bottom == top"); 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (near == far) { 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("near == far"); 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float r_width = 1.0f / (right - left); 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float r_height = 1.0f / (top - bottom); 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float r_depth = 1.0f / (far - near); 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float x = 2.0f * (r_width); 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float y = 2.0f * (r_height); 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float z = -2.0f * (r_depth); 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float tx = -(right + left) * r_width; 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float ty = -(top + bottom) * r_height; 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float tz = -(far + near) * r_depth; 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset + 0] = x; 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset + 5] = y; 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset +10] = z; 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset +12] = tx; 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset +13] = ty; 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset +14] = tz; 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset +15] = 1.0f; 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset + 1] = 0.0f; 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset + 2] = 0.0f; 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset + 3] = 0.0f; 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset + 4] = 0.0f; 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset + 6] = 0.0f; 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset + 7] = 0.0f; 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset + 8] = 0.0f; 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset + 9] = 0.0f; 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset + 11] = 0.0f; 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Define a projection matrix in terms of six clip planes 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param m the float array that holds the perspective matrix 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param offset the offset into float array m where the perspective 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * matrix data is written 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param left 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param right 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param bottom 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param top 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param near 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param far 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void frustumM(float[] m, int offset, 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float left, float right, float bottom, float top, 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float near, float far) { 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (left == right) { 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("left == right"); 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (top == bottom) { 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("top == bottom"); 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (near == far) { 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("near == far"); 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (near <= 0.0f) { 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("near <= 0.0f"); 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (far <= 0.0f) { 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("far <= 0.0f"); 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float r_width = 1.0f / (right - left); 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float r_height = 1.0f / (top - bottom); 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float r_depth = 1.0f / (near - far); 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float x = 2.0f * (near * r_width); 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float y = 2.0f * (near * r_height); 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float A = 2.0f * ((right + left) * r_width); 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float B = (top + bottom) * r_height; 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float C = (far + near) * r_depth; 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float D = 2.0f * (far * near * r_depth); 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 0] = x; 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 5] = y; 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 8] = A; 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 9] = B; 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 10] = C; 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 14] = D; 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 11] = -1.0f; 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 1] = 0.0f; 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 2] = 0.0f; 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 3] = 0.0f; 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 4] = 0.0f; 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 6] = 0.0f; 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 7] = 0.0f; 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 12] = 0.0f; 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 13] = 0.0f; 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 15] = 0.0f; 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Computes the length of a vector 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x x coordinate of a vector 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y y coordinate of a vector 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param z z coordinate of a vector 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the length of a vector 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static float length(float x, float y, float z) { 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (float) Math.sqrt(x * x + y * y + z * z); 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets matrix m to the identity matrix. 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sm returns the result 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param smOffset index into sm where the result matrix starts 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void setIdentityM(float[] sm, int smOffset) { 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<16 ; i++) { 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sm[smOffset + i] = 0; 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for(int i = 0; i < 16; i += 5) { 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sm[smOffset + i] = 1.0f; 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Scales matrix m by x, y, and z, putting the result in sm 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sm returns the result 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param smOffset index into sm where the result matrix starts 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param m source matrix 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mOffset index into m where the source matrix starts 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x scale factor x 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y scale factor y 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param z scale factor z 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void scaleM(float[] sm, int smOffset, 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] m, int mOffset, 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x, float y, float z) { 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<4 ; i++) { 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int smi = smOffset + i; 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mi = mOffset + i; 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sm[ smi] = m[ mi] * x; 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sm[ 4 + smi] = m[ 4 + mi] * y; 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sm[ 8 + smi] = m[ 8 + mi] * z; 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sm[12 + smi] = m[12 + mi]; 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Scales matrix m in place by sx, sy, and sz 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param m matrix to scale 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mOffset index into m where the matrix starts 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x scale factor x 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y scale factor y 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param z scale factor z 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void scaleM(float[] m, int mOffset, 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x, float y, float z) { 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<4 ; i++) { 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mi = mOffset + i; 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[ mi] *= x; 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[ 4 + mi] *= y; 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[ 8 + mi] *= z; 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Translates matrix m by x, y, and z, putting the result in tm 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param tm returns the result 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param tmOffset index into sm where the result matrix starts 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param m source matrix 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mOffset index into m where the source matrix starts 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x translation factor x 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y translation factor y 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param z translation factor z 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void translateM(float[] tm, int tmOffset, 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] m, int mOffset, 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x, float y, float z) { 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<12 ; i++) { 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tm[tmOffset + i] = m[mOffset + i]; 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<4 ; i++) { 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tmi = tmOffset + i; 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mi = mOffset + i; 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tm[12 + tmi] = m[mi] * x + m[4 + mi] * y + m[8 + mi] * z + 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[12 + mi]; 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Translates matrix m by x, y, and z in place. 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param m matrix 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mOffset index into m where the matrix starts 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x translation factor x 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y translation factor y 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param z translation factor z 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void translateM( 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] m, int mOffset, 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x, float y, float z) { 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<4 ; i++) { 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mi = mOffset + i; 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[12 + mi] += m[mi] * x + m[4 + mi] * y + m[8 + mi] * z; 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Rotates matrix m by angle a (in degrees) around the axis (x, y, z) 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rm returns the result 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rmOffset index into rm where the result matrix starts 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param m source matrix 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mOffset index into m where the source matrix starts 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param a angle to rotate in degrees 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x scale factor x 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y scale factor y 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param z scale factor z 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void rotateM(float[] rm, int rmOffset, 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] m, int mOffset, 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float a, float x, float y, float z) { 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] r = new float[16]; 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setRotateM(r, 0, a, x, y, z); 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project multiplyMM(rm, rmOffset, m, mOffset, r, 0); 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Rotates matrix m in place by angle a (in degrees) 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * around the axis (x, y, z) 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param m source matrix 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mOffset index into m where the matrix starts 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param a angle to rotate in degrees 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x scale factor x 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y scale factor y 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param z scale factor z 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void rotateM(float[] m, int mOffset, 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float a, float x, float y, float z) { 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] temp = new float[32]; 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setRotateM(temp, 0, a, x, y, z); 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project multiplyMM(temp, 16, m, mOffset, temp, 0); 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(temp, 16, m, mOffset, 16); 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Rotates matrix m by angle a (in degrees) around the axis (x, y, z) 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rm returns the result 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rmOffset index into rm where the result matrix starts 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param a angle to rotate in degrees 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x scale factor x 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y scale factor y 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param z scale factor z 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void setRotateM(float[] rm, int rmOffset, 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float a, float x, float y, float z) { 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 3] = 0; 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 7] = 0; 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 11]= 0; 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 12]= 0; 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 13]= 0; 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 14]= 0; 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 15]= 1; 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a *= (float) (Math.PI / 180.0f); 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float s = (float) Math.sin(a); 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float c = (float) Math.cos(a); 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (1.0f == x && 0.0f == y && 0.0f == z) { 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 5] = c; rm[rmOffset + 10]= c; 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 6] = s; rm[rmOffset + 9] = -s; 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 1] = 0; rm[rmOffset + 2] = 0; 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 4] = 0; rm[rmOffset + 8] = 0; 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 0] = 1; 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (0.0f == x && 1.0f == y && 0.0f == z) { 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 0] = c; rm[rmOffset + 10]= c; 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 8] = s; rm[rmOffset + 2] = -s; 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 1] = 0; rm[rmOffset + 4] = 0; 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 6] = 0; rm[rmOffset + 9] = 0; 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 5] = 1; 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (0.0f == x && 0.0f == y && 1.0f == z) { 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 0] = c; rm[rmOffset + 5] = c; 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 1] = s; rm[rmOffset + 4] = -s; 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 2] = 0; rm[rmOffset + 6] = 0; 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 8] = 0; rm[rmOffset + 9] = 0; 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 10]= 1; 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float len = length(x, y, z); 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (1.0f != len) { 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float recipLen = 1.0f / len; 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x *= recipLen; 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y *= recipLen; 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project z *= recipLen; 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float nc = 1.0f - c; 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float xy = x * y; 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float yz = y * z; 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float zx = z * x; 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float xs = x * s; 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float ys = y * s; 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float zs = z * s; 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 0] = x*x*nc + c; 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 4] = xy*nc - zs; 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 8] = zx*nc + ys; 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 1] = xy*nc + zs; 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 5] = y*y*nc + c; 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 9] = yz*nc - xs; 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 2] = zx*nc - ys; 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 6] = yz*nc + xs; 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 10] = z*z*nc + c; 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Converts Euler angles to a rotation matrix 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rm returns the result 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rmOffset index into rm where the result matrix starts 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x angle of rotation, in degrees 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y angle of rotation, in degrees 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param z angle of rotation, in degrees 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void setRotateEulerM(float[] rm, int rmOffset, 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x, float y, float z) { 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x *= (float) (Math.PI / 180.0f); 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y *= (float) (Math.PI / 180.0f); 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project z *= (float) (Math.PI / 180.0f); 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float cx = (float) Math.cos(x); 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float sx = (float) Math.sin(x); 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float cy = (float) Math.cos(y); 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float sy = (float) Math.sin(y); 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float cz = (float) Math.cos(z); 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float sz = (float) Math.sin(z); 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float cxsy = cx * sy; 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float sxsy = sx * sy; 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 0] = cy * cz; 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 1] = -cy * sz; 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 2] = sy; 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 3] = 0.0f; 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 4] = cxsy * cz + cx * sz; 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 5] = -cxsy * sz + cx * cz; 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 6] = -sx * cy; 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 7] = 0.0f; 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 8] = -sxsy * cz + sx * sz; 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 9] = sxsy * sz + sx * cz; 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 10] = cx * cy; 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 11] = 0.0f; 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 12] = 0.0f; 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 13] = 0.0f; 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 14] = 0.0f; 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 15] = 1.0f; 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 586