198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams/*
298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * Copyright (C) 2009-2012 The Android Open Source Project
398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams *
498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * Licensed under the Apache License, Version 2.0 (the "License");
598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * you may not use this file except in compliance with the License.
698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * You may obtain a copy of the License at
798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams *
898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams *      http://www.apache.org/licenses/LICENSE-2.0
998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams *
1098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * Unless required by applicable law or agreed to in writing, software
1198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * distributed under the License is distributed on an "AS IS" BASIS,
1298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * See the License for the specific language governing permissions and
1498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams * limitations under the License.
1598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams */
1698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
1798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Samspackage android.support.v8.renderscript;
1898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
1998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Samsimport java.lang.Math;
2098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Samsimport android.util.Log;
2198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
2298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
2398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams/**
247d435ae5ba100be5710b685653cc351cab159c11Stephen Hines * Class for exposing the native RenderScript rs_matrix4x4 type back to the Android system.
2598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams *
2698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams **/
2798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Samspublic class Matrix4f {
2898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
2998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
3098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * Creates a new identity 4x4 matrix
3198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    */
3298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public Matrix4f() {
3398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat = new float[16];
3498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        loadIdentity();
3598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
3698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
3798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
3898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * Creates a new matrix and sets its values from the given
3998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * parameter
4098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    *
4198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param dataArray values to set the matrix to, must be 16
4298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    *                  floats long
4398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    */
4498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public Matrix4f(float[] dataArray) {
4598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat = new float[16];
4698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
4798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
4898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
4998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
5098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * Return a reference to the internal array representing matrix
5198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * values. Modifying this array will also change the matrix
5298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    *
5398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @return internal array representing the matrix
5498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    */
5598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public float[] getArray() {
5698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        return mMat;
5798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
5898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
5998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
6098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * Returns the value for a given row and column
6198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    *
6298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param x column of the value to return
6398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param y row of the value to return
6498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    *
6598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @return value in the yth row and xth column
6698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    */
6798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public float get(int x, int y) {
6898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        return mMat[x*4 + y];
6998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
7098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
7198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
7298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * Sets the value for a given row and column
7398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    *
7498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param x column of the value to set
7598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param y row of the value to set
7698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    */
7798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public void set(int x, int y, float v) {
7898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[x*4 + y] = v;
7998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
8098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
8198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
8298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * Sets the matrix values to identity
8398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    */
8498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public void loadIdentity() {
8598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[0] = 1;
8698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[1] = 0;
8798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[2] = 0;
8898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[3] = 0;
8998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
9098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[4] = 0;
9198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[5] = 1;
9298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[6] = 0;
9398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[7] = 0;
9498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
9598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[8] = 0;
9698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[9] = 0;
9798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[10] = 1;
9898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[11] = 0;
9998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
10098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[12] = 0;
10198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[13] = 0;
10298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[14] = 0;
10398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[15] = 1;
10498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
10598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
10698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
10798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * Sets the values of the matrix to those of the parameter
10898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    *
10998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param src matrix to load the values from
11098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    */
11198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public void load(Matrix4f src) {
11298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        System.arraycopy(src.getArray(), 0, mMat, 0, mMat.length);
11398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
11498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
11598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
116ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    * Sets the values of the matrix to those of the parameter
117ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    *
118ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    * @param src matrix to load the values from
119ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    * @hide
120ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    */
121ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    public void load(Matrix3f src) {
122ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        mMat[0] = src.mMat[0];
123ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        mMat[1] = src.mMat[1];
124ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        mMat[2] = src.mMat[2];
125ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        mMat[3] = 0;
126ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
127ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        mMat[4] = src.mMat[3];
128ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        mMat[5] = src.mMat[4];
129ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        mMat[6] = src.mMat[5];
130ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        mMat[7] = 0;
131ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
132ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        mMat[8] = src.mMat[6];
133ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        mMat[9] = src.mMat[7];
134ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        mMat[10] = src.mMat[8];
135ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        mMat[11] = 0;
136ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
137ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        mMat[12] = 0;
138ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        mMat[13] = 0;
139ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        mMat[14] = 0;
140ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        mMat[15] = 1;
141ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    }
142ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
143ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    /**
14498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * Sets current values to be a rotation matrix of certain angle
14598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * about a given axis
14698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    *
14798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param rot angle of rotation
14898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param x rotation axis x
14998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param y rotation axis y
15098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param z rotation axis z
15198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    */
15298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public void loadRotate(float rot, float x, float y, float z) {
15398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        float c, s;
15498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[3] = 0;
15598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[7] = 0;
15698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[11]= 0;
15798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[12]= 0;
15898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[13]= 0;
15998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[14]= 0;
16098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[15]= 1;
16198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        rot *= (float)(java.lang.Math.PI / 180.0f);
16298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        c = (float)java.lang.Math.cos(rot);
16398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        s = (float)java.lang.Math.sin(rot);
16498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
16598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        float len = (float)java.lang.Math.sqrt(x*x + y*y + z*z);
16698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        if (!(len != 1)) {
16798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            float recipLen = 1.f / len;
16898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            x *= recipLen;
16998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            y *= recipLen;
17098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            z *= recipLen;
17198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        }
17298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        float nc = 1.0f - c;
17398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        float xy = x * y;
17498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        float yz = y * z;
17598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        float zx = z * x;
17698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        float xs = x * s;
17798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        float ys = y * s;
17898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        float zs = z * s;
17998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[ 0] = x*x*nc +  c;
18098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[ 4] =  xy*nc - zs;
18198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[ 8] =  zx*nc + ys;
18298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[ 1] =  xy*nc + zs;
18398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[ 5] = y*y*nc +  c;
18498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[ 9] =  yz*nc - xs;
18598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[ 2] =  zx*nc - ys;
18698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[ 6] =  yz*nc + xs;
18798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[10] = z*z*nc +  c;
18898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
18998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
19098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
19198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * Sets current values to be a scale matrix of given dimensions
19298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    *
19398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param x scale component x
19498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param y scale component y
19598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param z scale component z
19698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    */
19798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public void loadScale(float x, float y, float z) {
19898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        loadIdentity();
19998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[0] = x;
20098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[5] = y;
20198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[10] = z;
20298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
20398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
20498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
20598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * Sets current values to be a translation matrix of given
20698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * dimensions
20798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    *
20898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param x translation component x
20998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param y translation component y
21098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param z translation component z
21198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    */
21298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public void loadTranslate(float x, float y, float z) {
21398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        loadIdentity();
21498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[12] = x;
21598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[13] = y;
21698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[14] = z;
21798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
21898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
21998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
22098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * Sets current values to be the result of multiplying two given
22198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * matrices
22298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    *
22398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param lhs left hand side matrix
22498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param rhs right hand side matrix
22598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    */
22698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public void loadMultiply(Matrix4f lhs, Matrix4f rhs) {
22798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        for (int i=0 ; i<4 ; i++) {
22898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            float ri0 = 0;
22998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            float ri1 = 0;
23098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            float ri2 = 0;
23198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            float ri3 = 0;
23298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            for (int j=0 ; j<4 ; j++) {
23398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams                float rhs_ij = rhs.get(i,j);
23498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams                ri0 += lhs.get(j,0) * rhs_ij;
23598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams                ri1 += lhs.get(j,1) * rhs_ij;
23698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams                ri2 += lhs.get(j,2) * rhs_ij;
23798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams                ri3 += lhs.get(j,3) * rhs_ij;
23898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            }
23998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            set(i,0, ri0);
24098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            set(i,1, ri1);
24198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            set(i,2, ri2);
24298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            set(i,3, ri3);
24398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        }
24498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
24598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
24698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
24798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * Set current values to be an orthographic projection matrix
24898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    *
24998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param l location of the left vertical clipping plane
25098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param r location of the right vertical clipping plane
25198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param b location of the bottom horizontal clipping plane
25298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param t location of the top horizontal clipping plane
25398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param n location of the near clipping plane
25498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param f location of the far clipping plane
25598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    */
25698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public void loadOrtho(float l, float r, float b, float t, float n, float f) {
25798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        loadIdentity();
25898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[0] = 2 / (r - l);
25998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[5] = 2 / (t - b);
26098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[10]= -2 / (f - n);
26198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[12]= -(r + l) / (r - l);
26298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[13]= -(t + b) / (t - b);
26398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[14]= -(f + n) / (f - n);
26498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
26598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
26698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
26798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * Set current values to be an orthographic projection matrix
26898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * with the right and bottom clipping planes set to the given
26998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * values. Left and top clipping planes are set to 0. Near and
27098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * far are set to -1, 1 respectively
27198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    *
27298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param w location of the right vertical clipping plane
27398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param h location of the bottom horizontal clipping plane
27498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    *
27598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    */
27698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public void loadOrthoWindow(int w, int h) {
27798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        loadOrtho(0,w, h,0, -1,1);
27898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
27998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
28098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
28198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * Sets current values to be a perspective projection matrix
28298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    *
28398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param l location of the left vertical clipping plane
28498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param r location of the right vertical clipping plane
28598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param b location of the bottom horizontal clipping plane
28698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param t location of the top horizontal clipping plane
28798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param n location of the near clipping plane, must be positive
28898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param f location of the far clipping plane, must be positive
28998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    *
29098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    */
29198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public void loadFrustum(float l, float r, float b, float t, float n, float f) {
29298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        loadIdentity();
29398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[0] = 2 * n / (r - l);
29498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[5] = 2 * n / (t - b);
29598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[8] = (r + l) / (r - l);
29698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[9] = (t + b) / (t - b);
29798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[10]= -(f + n) / (f - n);
29898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[11]= -1;
29998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[14]= -2*f*n / (f - n);
30098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        mMat[15]= 0;
30198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
30298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
30398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
30498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * Sets current values to be a perspective projection matrix
30598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    *
30698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param fovy vertical field of view angle in degrees
30798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param aspect aspect ratio of the screen
30898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param near near cliping plane, must be positive
30998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param far far clipping plane, must be positive
31098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    */
31198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public void loadPerspective(float fovy, float aspect, float near, float far) {
31298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        float top = near * (float)Math.tan((float) (fovy * Math.PI / 360.0f));
31398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        float bottom = -top;
31498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        float left = bottom * aspect;
31598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        float right = top * aspect;
31698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        loadFrustum(left, right, bottom, top, near, far);
31798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
31898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
31998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
32098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * Helper function to set the current values to a perspective
32198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * projection matrix with aspect ratio defined by the parameters
32298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * and (near, far), (bottom, top) mapping to (-1, 1) at z = 0
32398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    *
32498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param w screen width
32598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param h screen height
32698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    */
32798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public void loadProjectionNormalized(int w, int h) {
32898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        // range -1,1 in the narrow axis at z = 0.
32998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        Matrix4f m1 = new Matrix4f();
33098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        Matrix4f m2 = new Matrix4f();
33198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
33298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        if(w > h) {
33398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            float aspect = ((float)w) / h;
33498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            m1.loadFrustum(-aspect,aspect,  -1,1,  1,100);
33598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        } else {
33698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            float aspect = ((float)h) / w;
33798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            m1.loadFrustum(-1,1, -aspect,aspect, 1,100);
33898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        }
33998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
34098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        m2.loadRotate(180, 0, 1, 0);
34198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        m1.loadMultiply(m1, m2);
34298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
34398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        m2.loadScale(-2, 2, 1);
34498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        m1.loadMultiply(m1, m2);
34598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
34698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        m2.loadTranslate(0, 0, 2);
34798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        m1.loadMultiply(m1, m2);
34898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
34998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        load(m1);
35098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
35198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
35298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
35398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * Post-multiplies the current matrix by a given parameter
35498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    *
35598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param rhs right hand side to multiply by
35698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    */
35798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public void multiply(Matrix4f rhs) {
35898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        Matrix4f tmp = new Matrix4f();
35998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        tmp.loadMultiply(this, rhs);
36098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        load(tmp);
36198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
36298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
36398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * Modifies the current matrix by post-multiplying it with a
36498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * rotation matrix of certain angle about a given axis
36598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    *
36698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param rot angle of rotation
36798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param x rotation axis x
36898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param y rotation axis y
36998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param z rotation axis z
37098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    */
37198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public void rotate(float rot, float x, float y, float z) {
37298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        Matrix4f tmp = new Matrix4f();
37398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        tmp.loadRotate(rot, x, y, z);
37498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        multiply(tmp);
37598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
37698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
37798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
37898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * Modifies the current matrix by post-multiplying it with a
37998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * scale matrix of given dimensions
38098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    *
38198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param x scale component x
38298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param y scale component y
38398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param z scale component z
38498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    */
38598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public void scale(float x, float y, float z) {
38698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        Matrix4f tmp = new Matrix4f();
38798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        tmp.loadScale(x, y, z);
38898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        multiply(tmp);
38998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
39098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
39198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
39298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * Modifies the current matrix by post-multiplying it with a
39398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * translation matrix of given dimensions
39498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    *
39598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param x translation component x
39698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param y translation component y
39798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * @param z translation component z
39898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    */
39998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public void translate(float x, float y, float z) {
40098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        Matrix4f tmp = new Matrix4f();
40198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        tmp.loadTranslate(x, y, z);
40298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        multiply(tmp);
40398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
40498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    private float computeCofactor(int i, int j) {
40598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        int c0 = (i+1) % 4;
40698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        int c1 = (i+2) % 4;
40798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        int c2 = (i+3) % 4;
40898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        int r0 = (j+1) % 4;
40998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        int r1 = (j+2) % 4;
41098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        int r2 = (j+3) % 4;
41198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
41298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        float minor = (mMat[c0 + 4*r0] * (mMat[c1 + 4*r1] * mMat[c2 + 4*r2] -
41398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams                                            mMat[c1 + 4*r2] * mMat[c2 + 4*r1]))
41498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams                     - (mMat[c0 + 4*r1] * (mMat[c1 + 4*r0] * mMat[c2 + 4*r2] -
41598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams                                            mMat[c1 + 4*r2] * mMat[c2 + 4*r0]))
41698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams                     + (mMat[c0 + 4*r2] * (mMat[c1 + 4*r0] * mMat[c2 + 4*r1] -
41798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams                                            mMat[c1 + 4*r1] * mMat[c2 + 4*r0]));
41898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
41998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        float cofactor = ((i+j) & 1) != 0 ? -minor : minor;
42098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        return cofactor;
42198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
42298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
42398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
42498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * Sets the current matrix to its inverse
42598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    */
42698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public boolean inverse() {
42798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
42898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        Matrix4f result = new Matrix4f();
42998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
43098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        for (int i = 0; i < 4; ++i) {
43198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            for (int j = 0; j < 4; ++j) {
43298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams                result.mMat[4*i + j] = computeCofactor(i, j);
43398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            }
43498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        }
43598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
43698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        // Dot product of 0th column of source and 0th row of result
43798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        float det = mMat[0]*result.mMat[0] + mMat[4]*result.mMat[1] +
43898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams                     mMat[8]*result.mMat[2] + mMat[12]*result.mMat[3];
43998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
44098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        if (Math.abs(det) < 1e-6) {
44198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            return false;
44298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        }
44398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
44498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        det = 1.0f / det;
44598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        for (int i = 0; i < 16; ++i) {
44698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            mMat[i] = result.mMat[i] * det;
44798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        }
44898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
44998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        return true;
45098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
45198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
45298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
45398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * Sets the current matrix to its inverse transpose
45498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    */
45598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public boolean inverseTranspose() {
45698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
45798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        Matrix4f result = new Matrix4f();
45898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
45998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        for (int i = 0; i < 4; ++i) {
46098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            for (int j = 0; j < 4; ++j) {
46198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams                result.mMat[4*j + i] = computeCofactor(i, j);
46298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            }
46398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        }
46498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
46598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        float det = mMat[0]*result.mMat[0] + mMat[4]*result.mMat[4] +
46698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams                     mMat[8]*result.mMat[8] + mMat[12]*result.mMat[12];
46798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
46898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        if (Math.abs(det) < 1e-6) {
46998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            return false;
47098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        }
47198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
47298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        det = 1.0f / det;
47398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        for (int i = 0; i < 16; ++i) {
47498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            mMat[i] = result.mMat[i] * det;
47598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        }
47698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
47798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        return true;
47898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
47998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
48098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    /**
48198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    * Sets the current matrix to its transpose
48298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    */
48398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    public void transpose() {
48498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        for(int i = 0; i < 3; ++i) {
48598a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            for(int j = i + 1; j < 4; ++j) {
48698a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams                float temp = mMat[i*4 + j];
48798a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams                mMat[i*4 + j] = mMat[j*4 + i];
48898a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams                mMat[j*4 + i] = temp;
48998a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams            }
49098a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams        }
49198a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    }
49298a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams
49398a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams    final float[] mMat;
49498a281354fe06d1f970d0521c9a08d9eb0aa1a45Jason Sams}
495