145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams/*
245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams * Copyright (C) 2009-2012 The Android Open Source Project
345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams *
445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams * Licensed under the Apache License, Version 2.0 (the "License");
545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams * you may not use this file except in compliance with the License.
645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams * You may obtain a copy of the License at
745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams *
845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams *      http://www.apache.org/licenses/LICENSE-2.0
945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams *
1045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams * Unless required by applicable law or agreed to in writing, software
1145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams * distributed under the License is distributed on an "AS IS" BASIS,
1245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams * See the License for the specific language governing permissions and
1445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams * limitations under the License.
1545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams */
1645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
1745d443665f5ce7efa934706a89883f0cc87f3513Jason Samspackage android.support.v8.renderscript;
1845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
1945d443665f5ce7efa934706a89883f0cc87f3513Jason Samsimport java.lang.Math;
2045d443665f5ce7efa934706a89883f0cc87f3513Jason Samsimport android.util.Log;
2145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
2245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
2345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams/**
24032b2c2c8a3cf2c55f6f08557f2648d799766c4eStephen Hines * Class for exposing the native RenderScript rs_matrix4x4 type back to the Android system.
2545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams *
2645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams **/
2745d443665f5ce7efa934706a89883f0cc87f3513Jason Samspublic class Matrix4f {
2845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
2945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    /**
3045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * Creates a new identity 4x4 matrix
3145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    */
3245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    public Matrix4f() {
3345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat = new float[16];
3445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        loadIdentity();
3545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    }
3645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
3745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    /**
3845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * Creates a new matrix and sets its values from the given
3945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * parameter
4045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    *
4145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param dataArray values to set the matrix to, must be 16
4245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    *                  floats long
4345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    */
4445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    public Matrix4f(float[] dataArray) {
4545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat = new float[16];
4645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
4745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    }
4845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
4945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    /**
5045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * Return a reference to the internal array representing matrix
5145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * values. Modifying this array will also change the matrix
5245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    *
5345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @return internal array representing the matrix
5445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    */
5545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    public float[] getArray() {
5645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        return mMat;
5745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    }
5845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
5945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    /**
6045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * Returns the value for a given row and column
6145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    *
6245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param x column of the value to return
6345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param y row of the value to return
6445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    *
6545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @return value in the yth row and xth column
6645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    */
6745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    public float get(int x, int y) {
6845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        return mMat[x*4 + y];
6945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    }
7045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
7145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    /**
7245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * Sets the value for a given row and column
7345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    *
7445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param x column of the value to set
7545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param y row of the value to set
7645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    */
7745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    public void set(int x, int y, float v) {
7845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[x*4 + y] = v;
7945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    }
8045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
8145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    /**
8245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * Sets the matrix values to identity
8345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    */
8445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    public void loadIdentity() {
8545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[0] = 1;
8645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[1] = 0;
8745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[2] = 0;
8845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[3] = 0;
8945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
9045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[4] = 0;
9145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[5] = 1;
9245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[6] = 0;
9345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[7] = 0;
9445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
9545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[8] = 0;
9645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[9] = 0;
9745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[10] = 1;
9845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[11] = 0;
9945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
10045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[12] = 0;
10145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[13] = 0;
10245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[14] = 0;
10345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[15] = 1;
10445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    }
10545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
10645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    /**
10745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * Sets the values of the matrix to those of the parameter
10845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    *
10945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param src matrix to load the values from
11045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    */
11145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    public void load(Matrix4f src) {
11245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        System.arraycopy(src.getArray(), 0, mMat, 0, mMat.length);
11345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    }
11445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
11545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    /**
116a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams    * Sets the values of the matrix to those of the parameter
117a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams    *
118a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams    * @param src matrix to load the values from
119a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams    * @hide
120a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams    */
121a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams    public void load(Matrix3f src) {
122a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams        mMat[0] = src.mMat[0];
123a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams        mMat[1] = src.mMat[1];
124a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams        mMat[2] = src.mMat[2];
125a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams        mMat[3] = 0;
126a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams
127a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams        mMat[4] = src.mMat[3];
128a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams        mMat[5] = src.mMat[4];
129a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams        mMat[6] = src.mMat[5];
130a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams        mMat[7] = 0;
131a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams
132a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams        mMat[8] = src.mMat[6];
133a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams        mMat[9] = src.mMat[7];
134a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams        mMat[10] = src.mMat[8];
135a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams        mMat[11] = 0;
136a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams
137a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams        mMat[12] = 0;
138a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams        mMat[13] = 0;
139a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams        mMat[14] = 0;
140a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams        mMat[15] = 1;
141a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams    }
142a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams
143a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams    /**
14445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * Sets current values to be a rotation matrix of certain angle
14545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * about a given axis
14645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    *
14745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param rot angle of rotation
14845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param x rotation axis x
14945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param y rotation axis y
15045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param z rotation axis z
15145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    */
15245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    public void loadRotate(float rot, float x, float y, float z) {
15345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        float c, s;
15445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[3] = 0;
15545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[7] = 0;
15645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[11]= 0;
15745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[12]= 0;
15845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[13]= 0;
15945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[14]= 0;
16045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[15]= 1;
16145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        rot *= (float)(java.lang.Math.PI / 180.0f);
16245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        c = (float)java.lang.Math.cos(rot);
16345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        s = (float)java.lang.Math.sin(rot);
16445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
16545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        float len = (float)java.lang.Math.sqrt(x*x + y*y + z*z);
16645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        if (!(len != 1)) {
16745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            float recipLen = 1.f / len;
16845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            x *= recipLen;
16945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            y *= recipLen;
17045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            z *= recipLen;
17145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        }
17245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        float nc = 1.0f - c;
17345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        float xy = x * y;
17445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        float yz = y * z;
17545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        float zx = z * x;
17645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        float xs = x * s;
17745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        float ys = y * s;
17845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        float zs = z * s;
17945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[ 0] = x*x*nc +  c;
18045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[ 4] =  xy*nc - zs;
18145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[ 8] =  zx*nc + ys;
18245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[ 1] =  xy*nc + zs;
18345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[ 5] = y*y*nc +  c;
18445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[ 9] =  yz*nc - xs;
18545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[ 2] =  zx*nc - ys;
18645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[ 6] =  yz*nc + xs;
18745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[10] = z*z*nc +  c;
18845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    }
18945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
19045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    /**
19145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * Sets current values to be a scale matrix of given dimensions
19245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    *
19345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param x scale component x
19445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param y scale component y
19545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param z scale component z
19645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    */
19745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    public void loadScale(float x, float y, float z) {
19845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        loadIdentity();
19945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[0] = x;
20045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[5] = y;
20145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[10] = z;
20245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    }
20345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
20445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    /**
20545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * Sets current values to be a translation matrix of given
20645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * dimensions
20745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    *
20845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param x translation component x
20945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param y translation component y
21045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param z translation component z
21145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    */
21245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    public void loadTranslate(float x, float y, float z) {
21345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        loadIdentity();
21445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[12] = x;
21545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[13] = y;
21645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[14] = z;
21745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    }
21845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
21945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    /**
22045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * Sets current values to be the result of multiplying two given
22145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * matrices
22245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    *
22345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param lhs left hand side matrix
22445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param rhs right hand side matrix
22545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    */
22645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    public void loadMultiply(Matrix4f lhs, Matrix4f rhs) {
22745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        for (int i=0 ; i<4 ; i++) {
22845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            float ri0 = 0;
22945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            float ri1 = 0;
23045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            float ri2 = 0;
23145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            float ri3 = 0;
23245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            for (int j=0 ; j<4 ; j++) {
23345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams                float rhs_ij = rhs.get(i,j);
23445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams                ri0 += lhs.get(j,0) * rhs_ij;
23545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams                ri1 += lhs.get(j,1) * rhs_ij;
23645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams                ri2 += lhs.get(j,2) * rhs_ij;
23745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams                ri3 += lhs.get(j,3) * rhs_ij;
23845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            }
23945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            set(i,0, ri0);
24045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            set(i,1, ri1);
24145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            set(i,2, ri2);
24245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            set(i,3, ri3);
24345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        }
24445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    }
24545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
24645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    /**
24745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * Set current values to be an orthographic projection matrix
24845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    *
24945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param l location of the left vertical clipping plane
25045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param r location of the right vertical clipping plane
25145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param b location of the bottom horizontal clipping plane
25245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param t location of the top horizontal clipping plane
25345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param n location of the near clipping plane
25445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param f location of the far clipping plane
25545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    */
25645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    public void loadOrtho(float l, float r, float b, float t, float n, float f) {
25745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        loadIdentity();
25845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[0] = 2 / (r - l);
25945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[5] = 2 / (t - b);
26045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[10]= -2 / (f - n);
26145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[12]= -(r + l) / (r - l);
26245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[13]= -(t + b) / (t - b);
26345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[14]= -(f + n) / (f - n);
26445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    }
26545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
26645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    /**
26745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * Set current values to be an orthographic projection matrix
26845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * with the right and bottom clipping planes set to the given
26945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * values. Left and top clipping planes are set to 0. Near and
27045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * far are set to -1, 1 respectively
27145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    *
27245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param w location of the right vertical clipping plane
27345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param h location of the bottom horizontal clipping plane
27445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    *
27545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    */
27645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    public void loadOrthoWindow(int w, int h) {
27745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        loadOrtho(0,w, h,0, -1,1);
27845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    }
27945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
28045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    /**
28145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * Sets current values to be a perspective projection matrix
28245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    *
28345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param l location of the left vertical clipping plane
28445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param r location of the right vertical clipping plane
28545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param b location of the bottom horizontal clipping plane
28645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param t location of the top horizontal clipping plane
28745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param n location of the near clipping plane, must be positive
28845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param f location of the far clipping plane, must be positive
28945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    *
29045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    */
29145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    public void loadFrustum(float l, float r, float b, float t, float n, float f) {
29245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        loadIdentity();
29345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[0] = 2 * n / (r - l);
29445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[5] = 2 * n / (t - b);
29545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[8] = (r + l) / (r - l);
29645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[9] = (t + b) / (t - b);
29745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[10]= -(f + n) / (f - n);
29845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[11]= -1;
29945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[14]= -2*f*n / (f - n);
30045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        mMat[15]= 0;
30145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    }
30245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
30345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    /**
30445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * Sets current values to be a perspective projection matrix
30545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    *
30645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param fovy vertical field of view angle in degrees
30745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param aspect aspect ratio of the screen
30845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param near near cliping plane, must be positive
30945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param far far clipping plane, must be positive
31045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    */
31145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    public void loadPerspective(float fovy, float aspect, float near, float far) {
31245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        float top = near * (float)Math.tan((float) (fovy * Math.PI / 360.0f));
31345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        float bottom = -top;
31445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        float left = bottom * aspect;
31545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        float right = top * aspect;
31645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        loadFrustum(left, right, bottom, top, near, far);
31745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    }
31845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
31945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    /**
32045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * Helper function to set the current values to a perspective
32145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * projection matrix with aspect ratio defined by the parameters
32245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * and (near, far), (bottom, top) mapping to (-1, 1) at z = 0
32345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    *
32445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param w screen width
32545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param h screen height
32645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    */
32745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    public void loadProjectionNormalized(int w, int h) {
32845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        // range -1,1 in the narrow axis at z = 0.
32945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        Matrix4f m1 = new Matrix4f();
33045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        Matrix4f m2 = new Matrix4f();
33145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
33245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        if(w > h) {
33345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            float aspect = ((float)w) / h;
33445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            m1.loadFrustum(-aspect,aspect,  -1,1,  1,100);
33545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        } else {
33645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            float aspect = ((float)h) / w;
33745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            m1.loadFrustum(-1,1, -aspect,aspect, 1,100);
33845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        }
33945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
34045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        m2.loadRotate(180, 0, 1, 0);
34145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        m1.loadMultiply(m1, m2);
34245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
34345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        m2.loadScale(-2, 2, 1);
34445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        m1.loadMultiply(m1, m2);
34545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
34645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        m2.loadTranslate(0, 0, 2);
34745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        m1.loadMultiply(m1, m2);
34845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
34945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        load(m1);
35045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    }
35145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
35245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    /**
35345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * Post-multiplies the current matrix by a given parameter
35445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    *
35545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param rhs right hand side to multiply by
35645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    */
35745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    public void multiply(Matrix4f rhs) {
35845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        Matrix4f tmp = new Matrix4f();
35945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        tmp.loadMultiply(this, rhs);
36045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        load(tmp);
36145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    }
36245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    /**
36345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * Modifies the current matrix by post-multiplying it with a
36445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * rotation matrix of certain angle about a given axis
36545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    *
36645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param rot angle of rotation
36745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param x rotation axis x
36845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param y rotation axis y
36945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param z rotation axis z
37045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    */
37145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    public void rotate(float rot, float x, float y, float z) {
37245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        Matrix4f tmp = new Matrix4f();
37345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        tmp.loadRotate(rot, x, y, z);
37445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        multiply(tmp);
37545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    }
37645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
37745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    /**
37845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * Modifies the current matrix by post-multiplying it with a
37945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * scale matrix of given dimensions
38045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    *
38145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param x scale component x
38245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param y scale component y
38345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param z scale component z
38445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    */
38545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    public void scale(float x, float y, float z) {
38645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        Matrix4f tmp = new Matrix4f();
38745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        tmp.loadScale(x, y, z);
38845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        multiply(tmp);
38945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    }
39045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
39145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    /**
39245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * Modifies the current matrix by post-multiplying it with a
39345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * translation matrix of given dimensions
39445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    *
39545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param x translation component x
39645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param y translation component y
39745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * @param z translation component z
39845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    */
39945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    public void translate(float x, float y, float z) {
40045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        Matrix4f tmp = new Matrix4f();
40145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        tmp.loadTranslate(x, y, z);
40245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        multiply(tmp);
40345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    }
40445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    private float computeCofactor(int i, int j) {
40545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        int c0 = (i+1) % 4;
40645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        int c1 = (i+2) % 4;
40745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        int c2 = (i+3) % 4;
40845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        int r0 = (j+1) % 4;
40945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        int r1 = (j+2) % 4;
41045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        int r2 = (j+3) % 4;
41145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
41245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        float minor = (mMat[c0 + 4*r0] * (mMat[c1 + 4*r1] * mMat[c2 + 4*r2] -
41345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams                                            mMat[c1 + 4*r2] * mMat[c2 + 4*r1]))
41445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams                     - (mMat[c0 + 4*r1] * (mMat[c1 + 4*r0] * mMat[c2 + 4*r2] -
41545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams                                            mMat[c1 + 4*r2] * mMat[c2 + 4*r0]))
41645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams                     + (mMat[c0 + 4*r2] * (mMat[c1 + 4*r0] * mMat[c2 + 4*r1] -
41745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams                                            mMat[c1 + 4*r1] * mMat[c2 + 4*r0]));
41845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
41945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        float cofactor = ((i+j) & 1) != 0 ? -minor : minor;
42045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        return cofactor;
42145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    }
42245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
42345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    /**
42445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * Sets the current matrix to its inverse
42545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    */
42645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    public boolean inverse() {
42745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
42845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        Matrix4f result = new Matrix4f();
42945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
43045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        for (int i = 0; i < 4; ++i) {
43145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            for (int j = 0; j < 4; ++j) {
43245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams                result.mMat[4*i + j] = computeCofactor(i, j);
43345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            }
43445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        }
43545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
43645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        // Dot product of 0th column of source and 0th row of result
43745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        float det = mMat[0]*result.mMat[0] + mMat[4]*result.mMat[1] +
43845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams                     mMat[8]*result.mMat[2] + mMat[12]*result.mMat[3];
43945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
44045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        if (Math.abs(det) < 1e-6) {
44145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            return false;
44245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        }
44345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
44445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        det = 1.0f / det;
44545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        for (int i = 0; i < 16; ++i) {
44645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            mMat[i] = result.mMat[i] * det;
44745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        }
44845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
44945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        return true;
45045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    }
45145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
45245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    /**
45345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * Sets the current matrix to its inverse transpose
45445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    */
45545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    public boolean inverseTranspose() {
45645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
45745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        Matrix4f result = new Matrix4f();
45845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
45945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        for (int i = 0; i < 4; ++i) {
46045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            for (int j = 0; j < 4; ++j) {
46145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams                result.mMat[4*j + i] = computeCofactor(i, j);
46245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            }
46345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        }
46445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
46545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        float det = mMat[0]*result.mMat[0] + mMat[4]*result.mMat[4] +
46645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams                     mMat[8]*result.mMat[8] + mMat[12]*result.mMat[12];
46745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
46845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        if (Math.abs(det) < 1e-6) {
46945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            return false;
47045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        }
47145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
47245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        det = 1.0f / det;
47345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        for (int i = 0; i < 16; ++i) {
47445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            mMat[i] = result.mMat[i] * det;
47545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        }
47645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
47745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        return true;
47845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    }
47945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
48045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    /**
48145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    * Sets the current matrix to its transpose
48245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    */
48345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    public void transpose() {
48445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        for(int i = 0; i < 3; ++i) {
48545d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            for(int j = i + 1; j < 4; ++j) {
48645d443665f5ce7efa934706a89883f0cc87f3513Jason Sams                float temp = mMat[i*4 + j];
48745d443665f5ce7efa934706a89883f0cc87f3513Jason Sams                mMat[i*4 + j] = mMat[j*4 + i];
48845d443665f5ce7efa934706a89883f0cc87f3513Jason Sams                mMat[j*4 + i] = temp;
48945d443665f5ce7efa934706a89883f0cc87f3513Jason Sams            }
49045d443665f5ce7efa934706a89883f0cc87f3513Jason Sams        }
49145d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    }
49245d443665f5ce7efa934706a89883f0cc87f3513Jason Sams
49345d443665f5ce7efa934706a89883f0cc87f3513Jason Sams    final float[] mMat;
49445d443665f5ce7efa934706a89883f0cc87f3513Jason Sams}
495