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. 22043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * <p> 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] 29043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * m[offset + 3] m[offset + 7] m[offset + 11] m[offset + 15]</pre> 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 31043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * Vectors are 4 x 1 column vectors stored in order: 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * v[offset + 0] 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * v[offset + 1] 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * v[offset + 2] 36043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * v[offset + 3]</pre> 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Matrix { 39cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich 40cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich /** Temporary memory for operations that need temporary matrix data. */ 41cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich private final static float[] sTemp = new float[32]; 42cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 44043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * @deprecated All methods are static, do not instantiate this class. 45043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden */ 46043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden @Deprecated 47043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden public Matrix() {} 48043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden 49043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden /** 50043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * Multiplies two 4x4 matrices together and stores the result in a third 4x4 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * matrix. In matrix notation: result = lhs x rhs. Due to the way 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * matrix multiplication works, the result matrix will have the same 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * effect as first multiplying by the rhs matrix, then multiplying by 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the lhs matrix. This is the opposite of what you might expect. 55043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * <p> 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The same float array may be passed for result, lhs, and/or rhs. However, 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the result element values are undefined if the result elements overlap 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * either the lhs or rhs elements. 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param result The float array that holds the result. 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param resultOffset The offset into the result array where the result is 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * stored. 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param lhs The float array that holds the left-hand-side matrix. 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param lhsOffset The offset into the lhs array where the lhs is stored 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rhs The float array that holds the right-hand-side matrix. 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rhsOffset The offset into the rhs array where the rhs is stored. 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalArgumentException if result, lhs, or rhs are null, or if 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * resultOffset + 16 > result.length or lhsOffset + 16 > lhs.length or 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * rhsOffset + 16 > rhs.length. 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static native void multiplyMM(float[] result, int resultOffset, 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] lhs, int lhsOffset, float[] rhs, int rhsOffset); 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 76043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * Multiplies a 4 element vector by a 4x4 matrix and stores the result in a 77043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * 4-element column vector. In matrix notation: result = lhs x rhs 78043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * <p> 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The same float array may be passed for resultVec, lhsMat, and/or rhsVec. 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * However, the resultVec element values are undefined if the resultVec 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * elements overlap either the lhsMat or rhsVec elements. 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param resultVec The float array that holds the result vector. 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param resultVecOffset The offset into the result array where the result 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * vector is stored. 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param lhsMat The float array that holds the left-hand-side matrix. 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param lhsMatOffset The offset into the lhs array where the lhs is stored 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rhsVec The float array that holds the right-hand-side vector. 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rhsVecOffset The offset into the rhs vector where the rhs vector 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is stored. 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalArgumentException if resultVec, lhsMat, 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or rhsVec are null, or if resultVecOffset + 4 > resultVec.length 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or lhsMatOffset + 16 > lhsMat.length or 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * rhsVecOffset + 4 > rhsVec.length. 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static native void multiplyMV(float[] resultVec, 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int resultVecOffset, float[] lhsMat, int lhsMatOffset, 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] rhsVec, int rhsVecOffset); 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Transposes a 4 x 4 matrix. 103043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * <p> 104043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * mTrans and m must not overlap. 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 106043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * @param mTrans the array that holds the output transposed matrix 107043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * @param mTransOffset an offset into mTrans where the transposed matrix is 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * stored. 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param m the input array 110043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * @param mOffset an offset into m where the input matrix is stored. 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void transposeM(float[] mTrans, int mTransOffset, float[] m, 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mOffset) { 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < 4; i++) { 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mBase = i * 4 + mOffset; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTrans[i + mTransOffset] = m[mBase]; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTrans[i + 4 + mTransOffset] = m[mBase + 1]; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTrans[i + 8 + mTransOffset] = m[mBase + 2]; 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTrans[i + 12 + mTransOffset] = m[mBase + 3]; 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inverts a 4 x 4 matrix. 125043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * <p> 126043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * mInv and m must not overlap. 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mInv the array that holds the output inverted matrix 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mInvOffset an offset into mInv where the inverted matrix is 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * stored. 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param m the input array 132043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * @param mOffset an offset into m where the input matrix is stored. 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the matrix could be inverted, false if it could not. 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean invertM(float[] mInv, int mInvOffset, float[] m, 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mOffset) { 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Invert a 4 x 4 matrix using Cramer's Rule 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // transpose matrix 140cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float src0 = m[mOffset + 0]; 141cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float src4 = m[mOffset + 1]; 142cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float src8 = m[mOffset + 2]; 143cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float src12 = m[mOffset + 3]; 144cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich 145cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float src1 = m[mOffset + 4]; 146cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float src5 = m[mOffset + 5]; 147cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float src9 = m[mOffset + 6]; 148cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float src13 = m[mOffset + 7]; 149cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich 150cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float src2 = m[mOffset + 8]; 151cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float src6 = m[mOffset + 9]; 152cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float src10 = m[mOffset + 10]; 153cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float src14 = m[mOffset + 11]; 154cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich 155cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float src3 = m[mOffset + 12]; 156cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float src7 = m[mOffset + 13]; 157cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float src11 = m[mOffset + 14]; 158cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float src15 = m[mOffset + 15]; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // calculate pairs for first 8 elements (cofactors) 161cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float atmp0 = src10 * src15; 162cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float atmp1 = src11 * src14; 163cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float atmp2 = src9 * src15; 164cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float atmp3 = src11 * src13; 165cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float atmp4 = src9 * src14; 166cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float atmp5 = src10 * src13; 167cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float atmp6 = src8 * src15; 168cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float atmp7 = src11 * src12; 169cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float atmp8 = src8 * src14; 170cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float atmp9 = src10 * src12; 171cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float atmp10 = src8 * src13; 172cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float atmp11 = src9 * src12; 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // calculate first 8 elements (cofactors) 175cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float dst0 = (atmp0 * src5 + atmp3 * src6 + atmp4 * src7) 176cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich - (atmp1 * src5 + atmp2 * src6 + atmp5 * src7); 177cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float dst1 = (atmp1 * src4 + atmp6 * src6 + atmp9 * src7) 178cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich - (atmp0 * src4 + atmp7 * src6 + atmp8 * src7); 179cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float dst2 = (atmp2 * src4 + atmp7 * src5 + atmp10 * src7) 180cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich - (atmp3 * src4 + atmp6 * src5 + atmp11 * src7); 181cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float dst3 = (atmp5 * src4 + atmp8 * src5 + atmp11 * src6) 182cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich - (atmp4 * src4 + atmp9 * src5 + atmp10 * src6); 183cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float dst4 = (atmp1 * src1 + atmp2 * src2 + atmp5 * src3) 184cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich - (atmp0 * src1 + atmp3 * src2 + atmp4 * src3); 185cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float dst5 = (atmp0 * src0 + atmp7 * src2 + atmp8 * src3) 186cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich - (atmp1 * src0 + atmp6 * src2 + atmp9 * src3); 187cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float dst6 = (atmp3 * src0 + atmp6 * src1 + atmp11 * src3) 188cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich - (atmp2 * src0 + atmp7 * src1 + atmp10 * src3); 189cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float dst7 = (atmp4 * src0 + atmp9 * src1 + atmp10 * src2) 190cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich - (atmp5 * src0 + atmp8 * src1 + atmp11 * src2); 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // calculate pairs for second 8 elements (cofactors) 193cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float btmp0 = src2 * src7; 194cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float btmp1 = src3 * src6; 195cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float btmp2 = src1 * src7; 196cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float btmp3 = src3 * src5; 197cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float btmp4 = src1 * src6; 198cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float btmp5 = src2 * src5; 199cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float btmp6 = src0 * src7; 200cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float btmp7 = src3 * src4; 201cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float btmp8 = src0 * src6; 202cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float btmp9 = src2 * src4; 203cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float btmp10 = src0 * src5; 204cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float btmp11 = src1 * src4; 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // calculate second 8 elements (cofactors) 207cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float dst8 = (btmp0 * src13 + btmp3 * src14 + btmp4 * src15) 208cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich - (btmp1 * src13 + btmp2 * src14 + btmp5 * src15); 209cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float dst9 = (btmp1 * src12 + btmp6 * src14 + btmp9 * src15) 210cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich - (btmp0 * src12 + btmp7 * src14 + btmp8 * src15); 211cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float dst10 = (btmp2 * src12 + btmp7 * src13 + btmp10 * src15) 212cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich - (btmp3 * src12 + btmp6 * src13 + btmp11 * src15); 213cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float dst11 = (btmp5 * src12 + btmp8 * src13 + btmp11 * src14) 214cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich - (btmp4 * src12 + btmp9 * src13 + btmp10 * src14); 215cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float dst12 = (btmp2 * src10 + btmp5 * src11 + btmp1 * src9 ) 216cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich - (btmp4 * src11 + btmp0 * src9 + btmp3 * src10); 217cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float dst13 = (btmp8 * src11 + btmp0 * src8 + btmp7 * src10) 218cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich - (btmp6 * src10 + btmp9 * src11 + btmp1 * src8 ); 219cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float dst14 = (btmp6 * src9 + btmp11 * src11 + btmp3 * src8 ) 220cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich - (btmp10 * src11 + btmp2 * src8 + btmp7 * src9 ); 221cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float dst15 = (btmp10 * src10 + btmp4 * src8 + btmp9 * src9 ) 222cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich - (btmp8 * src9 + btmp11 * src10 + btmp5 * src8 ); 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // calculate determinant 225cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float det = 226cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich src0 * dst0 + src1 * dst1 + src2 * dst2 + src3 * dst3; 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (det == 0.0f) { 229cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich return false; 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // calculate matrix inverse 233cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich final float invdet = 1.0f / det; 234cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich mInv[ mInvOffset] = dst0 * invdet; 235cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich mInv[ 1 + mInvOffset] = dst1 * invdet; 236cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich mInv[ 2 + mInvOffset] = dst2 * invdet; 237cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich mInv[ 3 + mInvOffset] = dst3 * invdet; 238cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich 239cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich mInv[ 4 + mInvOffset] = dst4 * invdet; 240cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich mInv[ 5 + mInvOffset] = dst5 * invdet; 241cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich mInv[ 6 + mInvOffset] = dst6 * invdet; 242cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich mInv[ 7 + mInvOffset] = dst7 * invdet; 243cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich 244cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich mInv[ 8 + mInvOffset] = dst8 * invdet; 245cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich mInv[ 9 + mInvOffset] = dst9 * invdet; 246cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich mInv[10 + mInvOffset] = dst10 * invdet; 247cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich mInv[11 + mInvOffset] = dst11 * invdet; 248cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich 249cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich mInv[12 + mInvOffset] = dst12 * invdet; 250cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich mInv[13 + mInvOffset] = dst13 * invdet; 251cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich mInv[14 + mInvOffset] = dst14 * invdet; 252cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich mInv[15 + mInvOffset] = dst15 * invdet; 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Computes an orthographic projection matrix. 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param m returns the result 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mOffset 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param left 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param right 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param bottom 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param top 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param near 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param far 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void orthoM(float[] m, int mOffset, 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float left, float right, float bottom, float top, 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float near, float far) { 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (left == right) { 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("left == right"); 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bottom == top) { 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("bottom == top"); 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (near == far) { 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("near == far"); 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float r_width = 1.0f / (right - left); 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float r_height = 1.0f / (top - bottom); 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float r_depth = 1.0f / (far - near); 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float x = 2.0f * (r_width); 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float y = 2.0f * (r_height); 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float z = -2.0f * (r_depth); 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float tx = -(right + left) * r_width; 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float ty = -(top + bottom) * r_height; 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float tz = -(far + near) * r_depth; 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset + 0] = x; 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset + 5] = y; 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset +10] = z; 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset +12] = tx; 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset +13] = ty; 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset +14] = tz; 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset +15] = 1.0f; 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset + 1] = 0.0f; 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset + 2] = 0.0f; 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset + 3] = 0.0f; 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset + 4] = 0.0f; 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset + 6] = 0.0f; 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset + 7] = 0.0f; 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset + 8] = 0.0f; 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset + 9] = 0.0f; 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[mOffset + 11] = 0.0f; 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 311043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * Defines a projection matrix in terms of six clip planes. 312043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * 313043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * @param m the float array that holds the output perspective matrix 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param offset the offset into float array m where the perspective 315043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * matrix data is written 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param left 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param right 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param bottom 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param top 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param near 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param far 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void frustumM(float[] m, int offset, 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float left, float right, float bottom, float top, 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float near, float far) { 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (left == right) { 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("left == right"); 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (top == bottom) { 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("top == bottom"); 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (near == far) { 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("near == far"); 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (near <= 0.0f) { 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("near <= 0.0f"); 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (far <= 0.0f) { 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("far <= 0.0f"); 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float r_width = 1.0f / (right - left); 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float r_height = 1.0f / (top - bottom); 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float r_depth = 1.0f / (near - far); 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float x = 2.0f * (near * r_width); 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float y = 2.0f * (near * r_height); 3460a088f5d4681fd2da6f610de157bf905df787bf7Romain Guy final float A = (right + left) * r_width; 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float B = (top + bottom) * r_height; 34842e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy final float C = (far + near) * r_depth; 34942e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy final float D = 2.0f * (far * near * r_depth); 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 0] = x; 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 5] = y; 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 8] = A; 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 9] = B; 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 10] = C; 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 14] = D; 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 11] = -1.0f; 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 1] = 0.0f; 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 2] = 0.0f; 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 3] = 0.0f; 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 4] = 0.0f; 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 6] = 0.0f; 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 7] = 0.0f; 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 12] = 0.0f; 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 13] = 0.0f; 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[offset + 15] = 0.0f; 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 369043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * Defines a projection matrix in terms of a field of view angle, an 370043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * aspect ratio, and z clip planes. 371043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * 372d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich * @param m the float array that holds the perspective matrix 373d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich * @param offset the offset into float array m where the perspective 374043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * matrix data is written 375d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich * @param fovy field of view in y direction, in degrees 376d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich * @param aspect width to height aspect ratio of the viewport 377d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich * @param zNear 378d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich * @param zFar 379d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich */ 380d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich public static void perspectiveM(float[] m, int offset, 381d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich float fovy, float aspect, float zNear, float zFar) { 382d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich float f = 1.0f / (float) Math.tan(fovy * (Math.PI / 360.0)); 383d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich float rangeReciprocal = 1.0f / (zNear - zFar); 384d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich 385d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich m[offset + 0] = f / aspect; 386d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich m[offset + 1] = 0.0f; 387d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich m[offset + 2] = 0.0f; 388d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich m[offset + 3] = 0.0f; 389d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich 390d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich m[offset + 4] = 0.0f; 391d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich m[offset + 5] = f; 392d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich m[offset + 6] = 0.0f; 393d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich m[offset + 7] = 0.0f; 394d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich 395d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich m[offset + 8] = 0.0f; 396d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich m[offset + 9] = 0.0f; 397d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich m[offset + 10] = (zFar + zNear) * rangeReciprocal; 398d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich m[offset + 11] = -1.0f; 399d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich 400d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich m[offset + 12] = 0.0f; 401d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich m[offset + 13] = 0.0f; 4027c80244afb9098c75b127c2d785bb6e5b03d68c5Jack Palevich m[offset + 14] = 2.0f * zFar * zNear * rangeReciprocal; 403d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich m[offset + 15] = 0.0f; 404d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich } 405d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich 406d793299e875a97dc73e04e3beb2a2865563dccdbJack Palevich /** 407043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * Computes the length of a vector. 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x x coordinate of a vector 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y y coordinate of a vector 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param z z coordinate of a vector 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the length of a vector 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static float length(float x, float y, float z) { 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (float) Math.sqrt(x * x + y * y + z * z); 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets matrix m to the identity matrix. 420043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sm returns the result 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param smOffset index into sm where the result matrix starts 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void setIdentityM(float[] sm, int smOffset) { 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<16 ; i++) { 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sm[smOffset + i] = 0; 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for(int i = 0; i < 16; i += 5) { 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sm[smOffset + i] = 1.0f; 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 434043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * Scales matrix m by x, y, and z, putting the result in sm. 435043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * <p> 436043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * m and sm must not overlap. 437043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sm returns the result 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param smOffset index into sm where the result matrix starts 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param m source matrix 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mOffset index into m where the source matrix starts 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x scale factor x 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y scale factor y 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param z scale factor z 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void scaleM(float[] sm, int smOffset, 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] m, int mOffset, 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x, float y, float z) { 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<4 ; i++) { 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int smi = smOffset + i; 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mi = mOffset + i; 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sm[ smi] = m[ mi] * x; 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sm[ 4 + smi] = m[ 4 + mi] * y; 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sm[ 8 + smi] = m[ 8 + mi] * z; 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sm[12 + smi] = m[12 + mi]; 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 460043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * Scales matrix m in place by sx, sy, and sz. 461043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param m matrix to scale 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mOffset index into m where the matrix starts 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x scale factor x 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y scale factor y 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param z scale factor z 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void scaleM(float[] m, int mOffset, 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x, float y, float z) { 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<4 ; i++) { 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mi = mOffset + i; 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[ mi] *= x; 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[ 4 + mi] *= y; 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[ 8 + mi] *= z; 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 479043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * Translates matrix m by x, y, and z, putting the result in tm. 480043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * <p> 481043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * m and tm must not overlap. 482043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param tm returns the result 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param tmOffset index into sm where the result matrix starts 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param m source matrix 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mOffset index into m where the source matrix starts 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x translation factor x 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y translation factor y 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param z translation factor z 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void translateM(float[] tm, int tmOffset, 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] m, int mOffset, 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x, float y, float z) { 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<12 ; i++) { 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tm[tmOffset + i] = m[mOffset + i]; 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<4 ; i++) { 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tmi = tmOffset + i; 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mi = mOffset + i; 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tm[12 + tmi] = m[mi] * x + m[4 + mi] * y + m[8 + mi] * z + 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[12 + mi]; 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Translates matrix m by x, y, and z in place. 507043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param m matrix 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mOffset index into m where the matrix starts 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x translation factor x 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y translation factor y 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param z translation factor z 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void translateM( 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] m, int mOffset, 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x, float y, float z) { 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<4 ; i++) { 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mi = mOffset + i; 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m[12 + mi] += m[mi] * x + m[4 + mi] * y + m[8 + mi] * z; 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 524043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * Rotates matrix m by angle a (in degrees) around the axis (x, y, z). 525043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * <p> 526043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * m and rm must not overlap. 527043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rm returns the result 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rmOffset index into rm where the result matrix starts 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param m source matrix 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mOffset index into m where the source matrix starts 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param a angle to rotate in degrees 533043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * @param x X axis component 534043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * @param y Y axis component 535043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * @param z Z axis component 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void rotateM(float[] rm, int rmOffset, 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] m, int mOffset, 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float a, float x, float y, float z) { 540cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich synchronized(sTemp) { 541cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich setRotateM(sTemp, 0, a, x, y, z); 542cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich multiplyMM(rm, rmOffset, m, mOffset, sTemp, 0); 543cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich } 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Rotates matrix m in place by angle a (in degrees) 548043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * around the axis (x, y, z). 549043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param m source matrix 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mOffset index into m where the matrix starts 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param a angle to rotate in degrees 553043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * @param x X axis component 554043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * @param y Y axis component 555043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * @param z Z axis component 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void rotateM(float[] m, int mOffset, 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float a, float x, float y, float z) { 559cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich synchronized(sTemp) { 560cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich setRotateM(sTemp, 0, a, x, y, z); 561cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich multiplyMM(sTemp, 16, m, mOffset, sTemp, 0); 562cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich System.arraycopy(sTemp, 16, m, mOffset, 16); 563cc5471c35327c1511075f5df0d45a2d57610fecbJack Palevich } 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 567043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * Creates a matrix for rotation by angle a (in degrees) 568043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * around the axis (x, y, z). 569043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * <p> 570043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * An optimized path will be used for rotation about a major axis 571043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * (e.g. x=1.0f y=0.0f z=0.0f). 572043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rm returns the result 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rmOffset index into rm where the result matrix starts 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param a angle to rotate in degrees 576043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * @param x X axis component 577043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * @param y Y axis component 578043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * @param z Z axis component 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void setRotateM(float[] rm, int rmOffset, 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float a, float x, float y, float z) { 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 3] = 0; 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 7] = 0; 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 11]= 0; 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 12]= 0; 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 13]= 0; 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 14]= 0; 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 15]= 1; 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a *= (float) (Math.PI / 180.0f); 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float s = (float) Math.sin(a); 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float c = (float) Math.cos(a); 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (1.0f == x && 0.0f == y && 0.0f == z) { 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 5] = c; rm[rmOffset + 10]= c; 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 6] = s; rm[rmOffset + 9] = -s; 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 1] = 0; rm[rmOffset + 2] = 0; 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 4] = 0; rm[rmOffset + 8] = 0; 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 0] = 1; 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (0.0f == x && 1.0f == y && 0.0f == z) { 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 0] = c; rm[rmOffset + 10]= c; 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 8] = s; rm[rmOffset + 2] = -s; 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 1] = 0; rm[rmOffset + 4] = 0; 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 6] = 0; rm[rmOffset + 9] = 0; 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 5] = 1; 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (0.0f == x && 0.0f == y && 1.0f == z) { 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 0] = c; rm[rmOffset + 5] = c; 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 1] = s; rm[rmOffset + 4] = -s; 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 2] = 0; rm[rmOffset + 6] = 0; 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 8] = 0; rm[rmOffset + 9] = 0; 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 10]= 1; 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float len = length(x, y, z); 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (1.0f != len) { 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float recipLen = 1.0f / len; 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x *= recipLen; 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y *= recipLen; 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project z *= recipLen; 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float nc = 1.0f - c; 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float xy = x * y; 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float yz = y * z; 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float zx = z * x; 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float xs = x * s; 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float ys = y * s; 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float zs = z * s; 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 0] = x*x*nc + c; 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 4] = xy*nc - zs; 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 8] = zx*nc + ys; 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 1] = xy*nc + zs; 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 5] = y*y*nc + c; 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 9] = yz*nc - xs; 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 2] = zx*nc - ys; 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 6] = yz*nc + xs; 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 10] = z*z*nc + c; 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 638043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * Converts Euler angles to a rotation matrix. 639043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rm returns the result 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rmOffset index into rm where the result matrix starts 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x angle of rotation, in degrees 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y angle of rotation, in degrees 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param z angle of rotation, in degrees 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void setRotateEulerM(float[] rm, int rmOffset, 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x, float y, float z) { 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x *= (float) (Math.PI / 180.0f); 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y *= (float) (Math.PI / 180.0f); 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project z *= (float) (Math.PI / 180.0f); 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float cx = (float) Math.cos(x); 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float sx = (float) Math.sin(x); 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float cy = (float) Math.cos(y); 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float sy = (float) Math.sin(y); 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float cz = (float) Math.cos(z); 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float sz = (float) Math.sin(z); 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float cxsy = cx * sy; 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float sxsy = sx * sy; 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 0] = cy * cz; 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 1] = -cy * sz; 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 2] = sy; 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 3] = 0.0f; 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 4] = cxsy * cz + cx * sz; 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 5] = -cxsy * sz + cx * cz; 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 6] = -sx * cy; 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 7] = 0.0f; 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 8] = -sxsy * cz + sx * sz; 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 9] = sxsy * sz + sx * cz; 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 10] = cx * cy; 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 11] = 0.0f; 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 12] = 0.0f; 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 13] = 0.0f; 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 14] = 0.0f; 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rm[rmOffset + 15] = 1.0f; 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 680355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich 681355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich /** 682043d13ad4b67b57fa8ba1fa35f48ff5bcc0f0141Andy McFadden * Defines a viewing transformation in terms of an eye point, a center of 683355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich * view, and an up vector. 684355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich * 685355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich * @param rm returns the result 686355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich * @param rmOffset index into rm where the result matrix starts 687355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich * @param eyeX eye point X 688355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich * @param eyeY eye point Y 689355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich * @param eyeZ eye point Z 690355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich * @param centerX center of view X 691355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich * @param centerY center of view Y 692355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich * @param centerZ center of view Z 693355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich * @param upX up vector X 694355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich * @param upY up vector Y 695355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich * @param upZ up vector Z 696355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich */ 697355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich public static void setLookAtM(float[] rm, int rmOffset, 698355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich float eyeX, float eyeY, float eyeZ, 699355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich float centerX, float centerY, float centerZ, float upX, float upY, 700355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich float upZ) { 701355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich 702355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich // See the OpenGL GLUT documentation for gluLookAt for a description 703355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich // of the algorithm. We implement it in a straightforward way: 704355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich 705355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich float fx = centerX - eyeX; 706355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich float fy = centerY - eyeY; 707355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich float fz = centerZ - eyeZ; 708355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich 709355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich // Normalize f 710355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich float rlf = 1.0f / Matrix.length(fx, fy, fz); 711355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich fx *= rlf; 712355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich fy *= rlf; 713355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich fz *= rlf; 714355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich 715355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich // compute s = f x up (x means "cross product") 716355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich float sx = fy * upZ - fz * upY; 717355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich float sy = fz * upX - fx * upZ; 718355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich float sz = fx * upY - fy * upX; 719355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich 720355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich // and normalize s 721355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich float rls = 1.0f / Matrix.length(sx, sy, sz); 722355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich sx *= rls; 723355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich sy *= rls; 724355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich sz *= rls; 725355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich 726355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich // compute u = s x f 727355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich float ux = sy * fz - sz * fy; 728355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich float uy = sz * fx - sx * fz; 729355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich float uz = sx * fy - sy * fx; 730355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich 731355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich rm[rmOffset + 0] = sx; 732355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich rm[rmOffset + 1] = ux; 733355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich rm[rmOffset + 2] = -fx; 734355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich rm[rmOffset + 3] = 0.0f; 735355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich 736355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich rm[rmOffset + 4] = sy; 737355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich rm[rmOffset + 5] = uy; 738355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich rm[rmOffset + 6] = -fy; 739355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich rm[rmOffset + 7] = 0.0f; 740355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich 741355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich rm[rmOffset + 8] = sz; 742355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich rm[rmOffset + 9] = uz; 743355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich rm[rmOffset + 10] = -fz; 744355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich rm[rmOffset + 11] = 0.0f; 745355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich 746355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich rm[rmOffset + 12] = 0.0f; 747355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich rm[rmOffset + 13] = 0.0f; 748355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich rm[rmOffset + 14] = 0.0f; 749355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich rm[rmOffset + 15] = 1.0f; 750355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich 751355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich translateM(rm, rmOffset, -eyeX, -eyeY, -eyeZ); 752355c20cb9276148fd9b7074c5199aedeb497406eJack Palevich } 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 754