diff options
author | phil <[email protected]> | 2017-01-08 15:57:42 +1300 |
---|---|---|
committer | phil <[email protected]> | 2017-01-08 15:57:42 +1300 |
commit | e803a9c992e1b210181433f257275bad92c45878 (patch) | |
tree | f896636b3592329b44801b2afd7f77814dc0903c | |
parent | 3ee9493a86109a5331bed939586afb60a0ebdef0 (diff) |
Actual support for a true GL2ES2 context
It turns out that a gl2es3 will be returned even if a es2 is asked for.
This means that some of the actions that were being performed were bad,
like transpose on setMatrix and set max texture lod
-rw-r--r-- | src/main/java/org/jogamp/java3d/Jogl2es2Context.java | 5 | ||||
-rw-r--r-- | src/main/java/org/jogamp/java3d/Jogl2es2MatrixUtil.java | 1949 | ||||
-rw-r--r-- | src/main/java/org/jogamp/java3d/Jogl2es2Pipeline.java | 58 |
3 files changed, 1036 insertions, 976 deletions
diff --git a/src/main/java/org/jogamp/java3d/Jogl2es2Context.java b/src/main/java/org/jogamp/java3d/Jogl2es2Context.java index cb41505..c6a0c48 100644 --- a/src/main/java/org/jogamp/java3d/Jogl2es2Context.java +++ b/src/main/java/org/jogamp/java3d/Jogl2es2Context.java @@ -50,7 +50,10 @@ public class Jogl2es2Context extends JoglContext public GL2ES3 gl2es3() { - return context.getGL().getGL2ES3(); + if(context.getGL().isGL2ES3()) + return context.getGL().getGL2ES3(); + else + return null; } public JoglShaderObject shaderProgram; diff --git a/src/main/java/org/jogamp/java3d/Jogl2es2MatrixUtil.java b/src/main/java/org/jogamp/java3d/Jogl2es2MatrixUtil.java index 8b513f0..6f13653 100644 --- a/src/main/java/org/jogamp/java3d/Jogl2es2MatrixUtil.java +++ b/src/main/java/org/jogamp/java3d/Jogl2es2MatrixUtil.java @@ -1,964 +1,987 @@ -/*
- * Copyright (c) 2016 JogAmp Community. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-package org.jogamp.java3d;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
-
-import org.jogamp.vecmath.Matrix3d;
-import org.jogamp.vecmath.Matrix4d;
-import org.jogamp.vecmath.SingularMatrixException;
-import org.jogamp.vecmath.Tuple4f;
-import org.jogamp.vecmath.Vector4f;
-
-/** class that demands single threading and uses deburners, don't touch if you don't understand, it will be bad...
- *
- * @author phil
- *
- */
-class Jogl2es2MatrixUtil
-{
-
- /**
- * Possibly faster
- * http://stackoverflow.com/questions/983999/simple-3x3-matrix-inverse-code-c
- */
-
- public static void transposeInvert(Matrix3d m, Matrix3d out)
- {
- double determinant = m.determinant();
- if (determinant > 0)
- {
- double invdet = 1 / determinant;
- out.m00 = (m.m11 * m.m22 - m.m21 * m.m12) * invdet;
- out.m10 = -(m.m01 * m.m22 - m.m02 * m.m21) * invdet;
- out.m20 = (m.m01 * m.m12 - m.m02 * m.m11) * invdet;
- out.m01 = -(m.m10 * m.m22 - m.m12 * m.m20) * invdet;
- out.m11 = (m.m00 * m.m22 - m.m02 * m.m20) * invdet;
- out.m21 = -(m.m00 * m.m12 - m.m10 * m.m02) * invdet;
- out.m02 = (m.m10 * m.m21 - m.m20 * m.m11) * invdet;
- out.m12 = -(m.m00 * m.m21 - m.m20 * m.m01) * invdet;
- out.m22 = (m.m00 * m.m11 - m.m10 * m.m01) * invdet;
- }
- else
- {
- out.setIdentity();
- }
- }
-
- /**
- * Only upper left 3x3 copied and transformed
- * @param m
- * @param out
- */
-
- public static void transposeInvert(Matrix4d m, Matrix3d out)
- {
- double determinant = m.determinant();
- if (determinant > 0)
- {
- double invdet = 1 / determinant;
- out.m00 = (m.m11 * m.m22 - m.m21 * m.m12) * invdet;
- out.m10 = -(m.m01 * m.m22 - m.m02 * m.m21) * invdet;
- out.m20 = (m.m01 * m.m12 - m.m02 * m.m11) * invdet;
- out.m01 = -(m.m10 * m.m22 - m.m12 * m.m20) * invdet;
- out.m11 = (m.m00 * m.m22 - m.m02 * m.m20) * invdet;
- out.m21 = -(m.m00 * m.m12 - m.m10 * m.m02) * invdet;
- out.m02 = (m.m10 * m.m21 - m.m20 * m.m11) * invdet;
- out.m12 = -(m.m00 * m.m21 - m.m20 * m.m01) * invdet;
- out.m22 = (m.m00 * m.m11 - m.m10 * m.m01) * invdet;
- }
- else
- {
- out.setIdentity();
- }
- }
-
- double result3[] = new double[9];
- int row_perm3[] = new int[3];
- double[] tmp3 = new double[9]; // scratch matrix
- //@See Matrix3d
-
- final void invertGeneral3(Matrix3d thisM, Matrix3d m1)
- {
- for (int i = 0; i < 3; i++)
- row_perm3[i] = 0;
-
- for (int i = 0; i < 9; i++)
- result3[i] = 0.0;
-
- // Use LU decomposition and backsubstitution code specifically
- // for floating-point 3x3 matrices.
-
- // Copy source matrix to t1tmp
- tmp3[0] = m1.m00;
- tmp3[1] = m1.m01;
- tmp3[2] = m1.m02;
-
- tmp3[3] = m1.m10;
- tmp3[4] = m1.m11;
- tmp3[5] = m1.m12;
-
- tmp3[6] = m1.m20;
- tmp3[7] = m1.m21;
- tmp3[8] = m1.m22;
-
- // Calculate LU decomposition: Is the matrix singular?
- if (!luDecomposition3(tmp3, row_perm3))
- {
- // Matrix has no inverse
- throw new SingularMatrixException("!luDecomposition(tmp, row_perm)");
- }
-
- // Perform back substitution on the identity matrix
-
- result3[0] = 1.0;
- result3[4] = 1.0;
- result3[8] = 1.0;
- luBacksubstitution3(tmp3, row_perm3, result3);
-
- thisM.m00 = result3[0];
- thisM.m01 = result3[1];
- thisM.m02 = result3[2];
-
- thisM.m10 = result3[3];
- thisM.m11 = result3[4];
- thisM.m12 = result3[5];
-
- thisM.m20 = result3[6];
- thisM.m21 = result3[7];
- thisM.m22 = result3[8];
-
- }
-
- double row_scale3[] = new double[3];
-
- //@See Matrix3d
- boolean luDecomposition3(double[] matrix0, int[] row_perm)
- {
- for (int i = 0; i < 3; i++)
- row_scale3[i] = 0.0;
- // Determine implicit scaling information by looping over rows
- {
- int i, j;
- int ptr, rs;
- double big, temp;
-
- ptr = 0;
- rs = 0;
-
- // For each row ...
- i = 3;
- while (i-- != 0)
- {
- big = 0.0;
-
- // For each column, find the largest element in the row
- j = 3;
- while (j-- != 0)
- {
- temp = matrix0[ptr++];
- temp = Math.abs(temp);
- if (temp > big)
- {
- big = temp;
- }
- }
-
- // Is the matrix singular?
- if (big == 0.0)
- {
- return false;
- }
- row_scale4[rs++] = 1.0 / big;
- }
- }
-
- {
- int j;
- int mtx;
-
- mtx = 0;
-
- // For all columns, execute Crout's method
- for (j = 0; j < 3; j++)
- {
- int i, imax, k;
- int target, p1, p2;
- double sum, big, temp;
-
- // Determine elements of upper diagonal matrix U
- for (i = 0; i < j; i++)
- {
- target = mtx + (3 * i) + j;
- sum = matrix0[target];
- k = i;
- p1 = mtx + (3 * i);
- p2 = mtx + j;
- while (k-- != 0)
- {
- sum -= matrix0[p1] * matrix0[p2];
- p1++;
- p2 += 3;
- }
- matrix0[target] = sum;
- }
-
- // Search for largest pivot element and calculate
- // intermediate elements of lower diagonal matrix L.
- big = 0.0;
- imax = -1;
- for (i = j; i < 3; i++)
- {
- target = mtx + (3 * i) + j;
- sum = matrix0[target];
- k = j;
- p1 = mtx + (3 * i);
- p2 = mtx + j;
- while (k-- != 0)
- {
- sum -= matrix0[p1] * matrix0[p2];
- p1++;
- p2 += 3;
- }
- matrix0[target] = sum;
-
- // Is this the best pivot so far?
- if ((temp = row_scale3[i] * Math.abs(sum)) >= big)
- {
- big = temp;
- imax = i;
- }
- }
-
- if (imax < 0)
- {
- throw new RuntimeException("imax < 0");
- }
-
- // Is a row exchange necessary?
- if (j != imax)
- {
- // Yes: exchange rows
- k = 3;
- p1 = mtx + (3 * imax);
- p2 = mtx + (3 * j);
- while (k-- != 0)
- {
- temp = matrix0[p1];
- matrix0[p1++] = matrix0[p2];
- matrix0[p2++] = temp;
- }
-
- // Record change in scale factor
- row_scale3[imax] = row_scale3[j];
- }
-
- // Record row permutation
- row_perm[j] = imax;
-
- // Is the matrix singular
- if (matrix0[(mtx + (3 * j) + j)] == 0.0)
- {
- return false;
- }
-
- // Divide elements of lower diagonal matrix L by pivot
- if (j != (3 - 1))
- {
- temp = 1.0 / (matrix0[(mtx + (3 * j) + j)]);
- target = mtx + (3 * (j + 1)) + j;
- i = 2 - j;
- while (i-- != 0)
- {
- matrix0[target] *= temp;
- target += 3;
- }
- }
- }
- }
-
- return true;
- }
-
- //@See Matrix3d
- void luBacksubstitution3(double[] matrix1, int[] row_perm, double[] matrix2)
- {
- int i, ii, ip, j, k;
- int rp;
- int cv, rv;
-
- // rp = row_perm;
- rp = 0;
-
- // For each column vector of matrix2 ...
- for (k = 0; k < 3; k++)
- {
- // cv = &(matrix2[0][k]);
- cv = k;
- ii = -1;
-
- // Forward substitution
- for (i = 0; i < 3; i++)
- {
- double sum;
-
- ip = row_perm[rp + i];
- sum = matrix2[cv + 3 * ip];
- matrix2[cv + 3 * ip] = matrix2[cv + 3 * i];
- if (ii >= 0)
- {
- // rv = &(matrix1[i][0]);
- rv = i * 3;
- for (j = ii; j <= i - 1; j++)
- {
- sum -= matrix1[rv + j] * matrix2[cv + 3 * j];
- }
- }
- else if (sum != 0.0)
- {
- ii = i;
- }
- matrix2[cv + 3 * i] = sum;
- }
-
- // Backsubstitution
- // rv = &(matrix1[3][0]);
- rv = 2 * 3;
- matrix2[cv + 3 * 2] /= matrix1[rv + 2];
-
- rv -= 3;
- matrix2[cv + 3 * 1] = (matrix2[cv + 3 * 1] - matrix1[rv + 2] * matrix2[cv + 3 * 2]) / matrix1[rv + 1];
-
- rv -= 3;
- matrix2[cv + 4 * 0] = (matrix2[cv + 3 * 0] - matrix1[rv + 1] * matrix2[cv + 3 * 1] - matrix1[rv + 2] * matrix2[cv + 3 * 2])
- / matrix1[rv + 0];
-
- }
- }
-
- double result4[] = new double[16];
- int row_perm4[] = new int[4];
- double[] tmp4 = new double[16]; // scratch matrix
-
- final void invertGeneral4(Matrix4d thisM, Matrix4d m1)
- {
- for (int i = 0; i < 4; i++)
- row_perm4[i] = 0;
-
- for (int i = 0; i < 16; i++)
- result4[i] = 0.0;
-
- // Use LU decomposition and backsubstitution code specifically
- // for floating-point 4x4 matrices.
-
- // Copy source matrix to t1tmp
- tmp4[0] = m1.m00;
- tmp4[1] = m1.m01;
- tmp4[2] = m1.m02;
- tmp4[3] = m1.m03;
-
- tmp4[4] = m1.m10;
- tmp4[5] = m1.m11;
- tmp4[6] = m1.m12;
- tmp4[7] = m1.m13;
-
- tmp4[8] = m1.m20;
- tmp4[9] = m1.m21;
- tmp4[10] = m1.m22;
- tmp4[11] = m1.m23;
-
- tmp4[12] = m1.m30;
- tmp4[13] = m1.m31;
- tmp4[14] = m1.m32;
- tmp4[15] = m1.m33;
-
- // Calculate LU decomposition: Is the matrix singular?
- if (!luDecomposition4(tmp4, row_perm4))
- {
- // Matrix has no inverse
- throw new SingularMatrixException("luDecomposition4(tmp4, row_perm4)");
- }
-
- // Perform back substitution on the identity matrix
- result4[0] = 1.0;
- result4[5] = 1.0;
- result4[10] = 1.0;
- result4[15] = 1.0;
- luBacksubstitution4(tmp4, row_perm4, result4);
-
- thisM.m00 = result4[0];
- thisM.m01 = result4[1];
- thisM.m02 = result4[2];
- thisM.m03 = result4[3];
-
- thisM.m10 = result4[4];
- thisM.m11 = result4[5];
- thisM.m12 = result4[6];
- thisM.m13 = result4[7];
-
- thisM.m20 = result4[8];
- thisM.m21 = result4[9];
- thisM.m22 = result4[10];
- thisM.m23 = result4[11];
-
- thisM.m30 = result4[12];
- thisM.m31 = result4[13];
- thisM.m32 = result4[14];
- thisM.m33 = result4[15];
-
- }
-
- double row_scale4[] = new double[4];
-
- boolean luDecomposition4(double[] matrix0, int[] row_perm)
- {
- for (int i = 0; i < 4; i++)
- row_scale4[i] = 0.0;
- // Determine implicit scaling information by looping over rows
- {
- int i, j;
- int ptr, rs;
- double big, temp;
-
- ptr = 0;
- rs = 0;
-
- // For each row ...
- i = 4;
- while (i-- != 0)
- {
- big = 0.0;
-
- // For each column, find the largest element in the row
- j = 4;
- while (j-- != 0)
- {
- temp = matrix0[ptr++];
- temp = Math.abs(temp);
- if (temp > big)
- {
- big = temp;
- }
- }
-
- // Is the matrix singular?
- if (big == 0.0)
- {
- return false;
- }
- row_scale4[rs++] = 1.0 / big;
- }
- }
-
- {
- int j;
- int mtx;
-
- mtx = 0;
-
- // For all columns, execute Crout's method
- for (j = 0; j < 4; j++)
- {
- int i, imax, k;
- int target, p1, p2;
- double sum, big, temp;
-
- // Determine elements of upper diagonal matrix U
- for (i = 0; i < j; i++)
- {
- target = mtx + (4 * i) + j;
- sum = matrix0[target];
- k = i;
- p1 = mtx + (4 * i);
- p2 = mtx + j;
- while (k-- != 0)
- {
- sum -= matrix0[p1] * matrix0[p2];
- p1++;
- p2 += 4;
- }
- matrix0[target] = sum;
- }
-
- // Search for largest pivot element and calculate
- // intermediate elements of lower diagonal matrix L.
- big = 0.0;
- imax = -1;
- for (i = j; i < 4; i++)
- {
- target = mtx + (4 * i) + j;
- sum = matrix0[target];
- k = j;
- p1 = mtx + (4 * i);
- p2 = mtx + j;
- while (k-- != 0)
- {
- sum -= matrix0[p1] * matrix0[p2];
- p1++;
- p2 += 4;
- }
- matrix0[target] = sum;
-
- // Is this the best pivot so far?
- if ((temp = row_scale4[i] * Math.abs(sum)) >= big)
- {
- big = temp;
- imax = i;
- }
- }
-
- if (imax < 0)
- {
- throw new RuntimeException("(imax < 0)");
- }
-
- // Is a row exchange necessary?
- if (j != imax)
- {
- // Yes: exchange rows
- k = 4;
- p1 = mtx + (4 * imax);
- p2 = mtx + (4 * j);
- while (k-- != 0)
- {
- temp = matrix0[p1];
- matrix0[p1++] = matrix0[p2];
- matrix0[p2++] = temp;
- }
-
- // Record change in scale factor
- row_scale4[imax] = row_scale4[j];
- }
-
- // Record row permutation
- row_perm[j] = imax;
-
- // Is the matrix singular
- if (matrix0[(mtx + (4 * j) + j)] == 0.0)
- {
- return false;
- }
-
- // Divide elements of lower diagonal matrix L by pivot
- if (j != (4 - 1))
- {
- temp = 1.0 / (matrix0[(mtx + (4 * j) + j)]);
- target = mtx + (4 * (j + 1)) + j;
- i = 3 - j;
- while (i-- != 0)
- {
- matrix0[target] *= temp;
- target += 4;
- }
- }
- }
- }
-
- return true;
- }
-
- void luBacksubstitution4(double[] matrix1, int[] row_perm, double[] matrix2)
- {
-
- int i, ii, ip, j, k;
- int rp;
- int cv, rv;
-
- // rp = row_perm;
- rp = 0;
-
- // For each column vector of matrix2 ...
- for (k = 0; k < 4; k++)
- {
- // cv = &(matrix2[0][k]);
- cv = k;
- ii = -1;
-
- // Forward substitution
- for (i = 0; i < 4; i++)
- {
- double sum;
-
- ip = row_perm[rp + i];
- sum = matrix2[cv + 4 * ip];
- matrix2[cv + 4 * ip] = matrix2[cv + 4 * i];
- if (ii >= 0)
- {
- // rv = &(matrix1[i][0]);
- rv = i * 4;
- for (j = ii; j <= i - 1; j++)
- {
- sum -= matrix1[rv + j] * matrix2[cv + 4 * j];
- }
- }
- else if (sum != 0.0)
- {
- ii = i;
- }
- matrix2[cv + 4 * i] = sum;
- }
-
- // Backsubstitution
- // rv = &(matrix1[3][0]);
- rv = 3 * 4;
- matrix2[cv + 4 * 3] /= matrix1[rv + 3];
-
- rv -= 4;
- matrix2[cv + 4 * 2] = (matrix2[cv + 4 * 2] - matrix1[rv + 3] * matrix2[cv + 4 * 3]) / matrix1[rv + 2];
-
- rv -= 4;
- matrix2[cv + 4 * 1] = (matrix2[cv + 4 * 1] - matrix1[rv + 2] * matrix2[cv + 4 * 2] - matrix1[rv + 3] * matrix2[cv + 4 * 3])
- / matrix1[rv + 1];
-
- rv -= 4;
- matrix2[cv + 4 * 0] = (matrix2[cv + 4 * 0] - matrix1[rv + 1] * matrix2[cv + 4 * 1] - matrix1[rv + 2] * matrix2[cv + 4 * 2]
- - matrix1[rv + 3] * matrix2[cv + 4 * 3]) / matrix1[rv + 0];
- }
- }
-
- public final void transform(Matrix4d m, Tuple4f vecOut)
- {
- float x, y, z;
-
- x = (float) (m.m00 * vecOut.x + m.m01 * vecOut.y + m.m02 * vecOut.z + m.m03 * vecOut.w);
- y = (float) (m.m10 * vecOut.x + m.m11 * vecOut.y + m.m12 * vecOut.z + m.m13 * vecOut.w);
- z = (float) (m.m20 * vecOut.x + m.m21 * vecOut.y + m.m22 * vecOut.z + m.m23 * vecOut.w);
- vecOut.w = (float) (m.m30 * vecOut.x + m.m31 * vecOut.y + m.m32 * vecOut.z + m.m33 * vecOut.w);
- vecOut.x = x;
- vecOut.y = y;
- vecOut.z = z;
- }
-
- //Oh lordy lordy yo' betta swear yo' single freadin' !!!
-
- public double[] deburnV2 = null;//deburners
-
- public Matrix4d deburnV = new Matrix4d();//deburners
- public Matrix4d deburnM = new Matrix4d();
- public float[] tempMat9 = new float[9];
- public float[] tempMat12 = new float[12];
- public float[] tempMat16 = new float[16];
- public double[] tempMatD9 = new double[9];
-
- public float[] toArray(Matrix4d m)
- {
- tempMat16[0] = (float) m.m00;
- tempMat16[1] = (float) m.m01;
- tempMat16[2] = (float) m.m02;
- tempMat16[3] = (float) m.m03;
- tempMat16[4] = (float) m.m10;
- tempMat16[5] = (float) m.m11;
- tempMat16[6] = (float) m.m12;
- tempMat16[7] = (float) m.m13;
- tempMat16[8] = (float) m.m20;
- tempMat16[9] = (float) m.m21;
- tempMat16[10] = (float) m.m22;
- tempMat16[11] = (float) m.m23;
- tempMat16[12] = (float) m.m30;
- tempMat16[13] = (float) m.m31;
- tempMat16[14] = (float) m.m32;
- tempMat16[15] = (float) m.m33;
- return tempMat16;
- }
-
- public static float[] toArray(Matrix4d m, float[] a)
- {
- a[0] = (float) m.m00;
- a[1] = (float) m.m01;
- a[2] = (float) m.m02;
- a[3] = (float) m.m03;
- a[4] = (float) m.m10;
- a[5] = (float) m.m11;
- a[6] = (float) m.m12;
- a[7] = (float) m.m13;
- a[8] = (float) m.m20;
- a[9] = (float) m.m21;
- a[10] = (float) m.m22;
- a[11] = (float) m.m23;
- a[12] = (float) m.m30;
- a[13] = (float) m.m31;
- a[14] = (float) m.m32;
- a[15] = (float) m.m33;
-
- return a;
- }
-
- public float[] toArray(Matrix3d m)
- {
- tempMat9[0] = (float) m.m00;
- tempMat9[1] = (float) m.m01;
- tempMat9[2] = (float) m.m02;
- tempMat9[3] = (float) m.m10;
- tempMat9[4] = (float) m.m11;
- tempMat9[5] = (float) m.m12;
- tempMat9[6] = (float) m.m20;
- tempMat9[7] = (float) m.m21;
- tempMat9[8] = (float) m.m22;
- return tempMat9;
-
- }
-
- public static float[] toArray(Matrix3d m, float[] a)
- {
- a[0] = (float) m.m00;
- a[1] = (float) m.m01;
- a[2] = (float) m.m02;
- a[3] = (float) m.m10;
- a[4] = (float) m.m11;
- a[5] = (float) m.m12;
- a[6] = (float) m.m20;
- a[7] = (float) m.m21;
- a[8] = (float) m.m22;
-
- return a;
- }
-
- public float[] toArray3x4(Matrix3d m)
- {
- return toArray3x4(m, tempMat12);
- }
-
- public static float[] toArray3x4(Matrix3d m, float[] a)
- {
- a[0] = (float) m.m00;
- a[1] = (float) m.m01;
- a[2] = (float) m.m02;
- a[3] = 0f;
- a[4] = (float) m.m10;
- a[5] = (float) m.m11;
- a[6] = (float) m.m12;
- a[7] = 0f;
- a[8] = (float) m.m20;
- a[9] = (float) m.m21;
- a[10] = (float) m.m22;
- a[11] = 0f;
-
- return a;
- }
-
- public double[] toArray3x3(Matrix4d m)
- {
- return toArray3x3(m, tempMatD9);
- }
-
- public static double[] toArray3x3(Matrix4d m, double[] a)
- {
- a[0] = m.m00;
- a[1] = m.m01;
- a[2] = m.m02;
- a[3] = m.m10;
- a[4] = m.m11;
- a[5] = m.m12;
- a[6] = m.m20;
- a[7] = m.m21;
- a[8] = m.m22;
-
- return a;
- }
-
- public void invert(Matrix3d m1)
- {
- try
- {
- invertGeneral3(m1, m1);
- }
- catch (Exception e)
- {
- //fine, move along
- m1.setIdentity();
- }
- }
-
- public void invert(Matrix4d m1)
- {
- try
- {
- invertGeneral4(m1, m1);
- }
- catch (Exception e)
- {
- //fine, move along
- m1.setIdentity();
- }
- }
-
- //More single threaded death-defying gear
- private Vector4f tmpV4f = new Vector4f();;
-
- public Vector4f transform(Matrix4d m1, Matrix4d m2, float tx, float ty, float tz, float tw)
- {
- tmpV4f.set(tx, ty, tz, tw);
- transform(m1, tmpV4f);
- transform(m2, tmpV4f);
- return tmpV4f;
- }
-
- private FloatBuffer matFB4x4;
-
- public FloatBuffer toFB4(float[] f)
- {
- if (matFB4x4 == null)
- {
- ByteBuffer bb = ByteBuffer.allocateDirect(16 * 4);
- bb.order(ByteOrder.nativeOrder());
- matFB4x4 = bb.asFloatBuffer();
- }
- matFB4x4.position(0);
- matFB4x4.put(f);
- matFB4x4.position(0);
- return matFB4x4;
- }
-
- public FloatBuffer toFB3(float[] f)
- {
- if (matFB3x3 == null)
- {
- ByteBuffer bb = ByteBuffer.allocateDirect(16 * 4);
- bb.order(ByteOrder.nativeOrder());
- matFB3x3 = bb.asFloatBuffer();
- }
- matFB3x3.position(0);
- matFB3x3.put(f);
- matFB3x3.position(0);
- return matFB3x3;
- }
-
- public FloatBuffer toFB(Matrix4d m)
- {
- if (matFB4x4 == null)
- {
- ByteBuffer bb = ByteBuffer.allocateDirect(16 * 4);
- bb.order(ByteOrder.nativeOrder());
- matFB4x4 = bb.asFloatBuffer();
- }
- matFB4x4.position(0);
- matFB4x4.put(toArray(m));
- matFB4x4.position(0);
- return matFB4x4;
- }
-
- private FloatBuffer matFB3x3;
-
- public FloatBuffer toFB(Matrix3d m)
- {
- if (matFB3x3 == null)
- {
- ByteBuffer bb = ByteBuffer.allocateDirect(9 * 4);
- bb.order(ByteOrder.nativeOrder());
- matFB3x3 = bb.asFloatBuffer();
- }
- matFB3x3.position(0);
- matFB3x3.put(toArray(m));
- matFB3x3.position(0);
- return matFB3x3;
- }
-
- // Not needed generally as transpose can be called on the inteface with gl
- public static float[] transposeInPlace(float[] src)
- {
- float v1 = src[1];
- float v2 = src[2];
- float v3 = src[3];
- float v6 = src[6];
- float v7 = src[7];
- float v11 = src[11];
-
- //src[0] = src[0];
- src[1] = src[4];
- src[2] = src[8];
- src[3] = src[12];
- src[4] = v1;
- //src[5] = src[5];
- src[6] = src[9];
- src[7] = src[13];
- src[8] = v2;
- src[9] = v6;
- //src[10] = src[10];
- src[11] = src[14];
- src[12] = v3;
- src[13] = v7;
- src[14] = v11;
- //src[15] = src[15];
-
- return src;
- }
-
- // ignores the higher 16 bits
- public static float halfToFloat(int hbits)
- {
- int mant = hbits & 0x03ff; // 10 bits mantissa
- int exp = hbits & 0x7c00; // 5 bits exponent
- if (exp == 0x7c00) // NaN/Inf
- exp = 0x3fc00; // -> NaN/Inf
- else if (exp != 0) // normalized value
- {
- exp += 0x1c000; // exp - 15 + 127
- if (mant == 0 && exp > 0x1c400) // smooth transition
- return Float.intBitsToFloat((hbits & 0x8000) << 16 | exp << 13 | 0x3ff);
- }
- else if (mant != 0) // && exp==0 -> subnormal
- {
- exp = 0x1c400; // make it normal
- do
- {
- mant <<= 1; // mantissa * 2
- exp -= 0x400; // decrease exp by 1
- }
- while ((mant & 0x400) == 0); // while not normal
- mant &= 0x3ff; // discard subnormal bit
- } // else +/-0 -> +/-0
- return Float.intBitsToFloat( // combine all parts
- (hbits & 0x8000) << 16 // sign << ( 31 - 15 )
- | (exp | mant) << 13); // value << ( 23 - 10 )
- }
-
- // returns all higher 16 bits as 0 for all results
- public static int halfFromFloat(float fval)
- {
- int fbits = Float.floatToIntBits(fval);
- int sign = fbits >>> 16 & 0x8000; // sign only
- int val = (fbits & 0x7fffffff) + 0x1000; // rounded value
-
- if (val >= 0x47800000) // might be or become NaN/Inf
- { // avoid Inf due to rounding
- if ((fbits & 0x7fffffff) >= 0x47800000)
- { // is or must become NaN/Inf
- if (val < 0x7f800000) // was value but too large
- return sign | 0x7c00; // make it +/-Inf
- return sign | 0x7c00 | // remains +/-Inf or NaN
- (fbits & 0x007fffff) >>> 13; // keep NaN (and Inf) bits
- }
- return sign | 0x7bff; // unrounded not quite Inf
- }
- if (val >= 0x38800000) // remains normalized value
- return sign | val - 0x38000000 >>> 13; // exp - 127 + 15
- if (val < 0x33000000) // too small for subnormal
- return sign; // becomes +/-0
- val = (fbits & 0x7fffffff) >>> 23; // tmp exp for subnormal calc
- return sign | ((fbits & 0x7fffff | 0x800000) // add subnormal bit
- + (0x800000 >>> val - 102) // round depending on cut off
- >>> 126 - val); // div by 2^(1-(exp-127+15)) and >> 13 | exp=0
- }
+/* + * Copyright (c) 2016 JogAmp Community. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +package org.jogamp.java3d; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; + +import org.jogamp.vecmath.Matrix3d; +import org.jogamp.vecmath.Matrix4d; +import org.jogamp.vecmath.SingularMatrixException; +import org.jogamp.vecmath.Tuple4f; +import org.jogamp.vecmath.Vector4f; + +/** class that demands single threading and uses deburners, don't touch if you don't understand, it will be bad... + * + * @author phil + * + */ +class Jogl2es2MatrixUtil +{ + + /** + * Possibly faster + * http://stackoverflow.com/questions/983999/simple-3x3-matrix-inverse-code-c + */ + + public static void transposeInvert(Matrix3d m, Matrix3d out) + { + double determinant = m.determinant(); + if (determinant > 0) + { + double invdet = 1 / determinant; + out.m00 = (m.m11 * m.m22 - m.m21 * m.m12) * invdet; + out.m10 = -(m.m01 * m.m22 - m.m02 * m.m21) * invdet; + out.m20 = (m.m01 * m.m12 - m.m02 * m.m11) * invdet; + out.m01 = -(m.m10 * m.m22 - m.m12 * m.m20) * invdet; + out.m11 = (m.m00 * m.m22 - m.m02 * m.m20) * invdet; + out.m21 = -(m.m00 * m.m12 - m.m10 * m.m02) * invdet; + out.m02 = (m.m10 * m.m21 - m.m20 * m.m11) * invdet; + out.m12 = -(m.m00 * m.m21 - m.m20 * m.m01) * invdet; + out.m22 = (m.m00 * m.m11 - m.m10 * m.m01) * invdet; + } + else + { + out.setIdentity(); + } + } + + /** + * Only upper left 3x3 copied and transformed + * @param m + * @param out + */ + + public static void transposeInvert(Matrix4d m, Matrix3d out) + { + double determinant = m.determinant(); + if (determinant > 0) + { + double invdet = 1 / determinant; + out.m00 = (m.m11 * m.m22 - m.m21 * m.m12) * invdet; + out.m10 = -(m.m01 * m.m22 - m.m02 * m.m21) * invdet; + out.m20 = (m.m01 * m.m12 - m.m02 * m.m11) * invdet; + out.m01 = -(m.m10 * m.m22 - m.m12 * m.m20) * invdet; + out.m11 = (m.m00 * m.m22 - m.m02 * m.m20) * invdet; + out.m21 = -(m.m00 * m.m12 - m.m10 * m.m02) * invdet; + out.m02 = (m.m10 * m.m21 - m.m20 * m.m11) * invdet; + out.m12 = -(m.m00 * m.m21 - m.m20 * m.m01) * invdet; + out.m22 = (m.m00 * m.m11 - m.m10 * m.m01) * invdet; + } + else + { + out.setIdentity(); + } + } + + double result3[] = new double[9]; + int row_perm3[] = new int[3]; + double[] tmp3 = new double[9]; // scratch matrix + //@See Matrix3d + + final void invertGeneral3(Matrix3d thisM, Matrix3d m1) + { + for (int i = 0; i < 3; i++) + row_perm3[i] = 0; + + for (int i = 0; i < 9; i++) + result3[i] = 0.0; + + // Use LU decomposition and backsubstitution code specifically + // for floating-point 3x3 matrices. + + // Copy source matrix to t1tmp + tmp3[0] = m1.m00; + tmp3[1] = m1.m01; + tmp3[2] = m1.m02; + + tmp3[3] = m1.m10; + tmp3[4] = m1.m11; + tmp3[5] = m1.m12; + + tmp3[6] = m1.m20; + tmp3[7] = m1.m21; + tmp3[8] = m1.m22; + + // Calculate LU decomposition: Is the matrix singular? + if (!luDecomposition3(tmp3, row_perm3)) + { + // Matrix has no inverse + throw new SingularMatrixException("!luDecomposition(tmp, row_perm)"); + } + + // Perform back substitution on the identity matrix + + result3[0] = 1.0; + result3[4] = 1.0; + result3[8] = 1.0; + luBacksubstitution3(tmp3, row_perm3, result3); + + thisM.m00 = result3[0]; + thisM.m01 = result3[1]; + thisM.m02 = result3[2]; + + thisM.m10 = result3[3]; + thisM.m11 = result3[4]; + thisM.m12 = result3[5]; + + thisM.m20 = result3[6]; + thisM.m21 = result3[7]; + thisM.m22 = result3[8]; + + } + + double row_scale3[] = new double[3]; + + //@See Matrix3d + boolean luDecomposition3(double[] matrix0, int[] row_perm) + { + for (int i = 0; i < 3; i++) + row_scale3[i] = 0.0; + // Determine implicit scaling information by looping over rows + { + int i, j; + int ptr, rs; + double big, temp; + + ptr = 0; + rs = 0; + + // For each row ... + i = 3; + while (i-- != 0) + { + big = 0.0; + + // For each column, find the largest element in the row + j = 3; + while (j-- != 0) + { + temp = matrix0[ptr++]; + temp = Math.abs(temp); + if (temp > big) + { + big = temp; + } + } + + // Is the matrix singular? + if (big == 0.0) + { + return false; + } + row_scale4[rs++] = 1.0 / big; + } + } + + { + int j; + int mtx; + + mtx = 0; + + // For all columns, execute Crout's method + for (j = 0; j < 3; j++) + { + int i, imax, k; + int target, p1, p2; + double sum, big, temp; + + // Determine elements of upper diagonal matrix U + for (i = 0; i < j; i++) + { + target = mtx + (3 * i) + j; + sum = matrix0[target]; + k = i; + p1 = mtx + (3 * i); + p2 = mtx + j; + while (k-- != 0) + { + sum -= matrix0[p1] * matrix0[p2]; + p1++; + p2 += 3; + } + matrix0[target] = sum; + } + + // Search for largest pivot element and calculate + // intermediate elements of lower diagonal matrix L. + big = 0.0; + imax = -1; + for (i = j; i < 3; i++) + { + target = mtx + (3 * i) + j; + sum = matrix0[target]; + k = j; + p1 = mtx + (3 * i); + p2 = mtx + j; + while (k-- != 0) + { + sum -= matrix0[p1] * matrix0[p2]; + p1++; + p2 += 3; + } + matrix0[target] = sum; + + // Is this the best pivot so far? + if ((temp = row_scale3[i] * Math.abs(sum)) >= big) + { + big = temp; + imax = i; + } + } + + if (imax < 0) + { + throw new RuntimeException("imax < 0"); + } + + // Is a row exchange necessary? + if (j != imax) + { + // Yes: exchange rows + k = 3; + p1 = mtx + (3 * imax); + p2 = mtx + (3 * j); + while (k-- != 0) + { + temp = matrix0[p1]; + matrix0[p1++] = matrix0[p2]; + matrix0[p2++] = temp; + } + + // Record change in scale factor + row_scale3[imax] = row_scale3[j]; + } + + // Record row permutation + row_perm[j] = imax; + + // Is the matrix singular + if (matrix0[(mtx + (3 * j) + j)] == 0.0) + { + return false; + } + + // Divide elements of lower diagonal matrix L by pivot + if (j != (3 - 1)) + { + temp = 1.0 / (matrix0[(mtx + (3 * j) + j)]); + target = mtx + (3 * (j + 1)) + j; + i = 2 - j; + while (i-- != 0) + { + matrix0[target] *= temp; + target += 3; + } + } + } + } + + return true; + } + + //@See Matrix3d + void luBacksubstitution3(double[] matrix1, int[] row_perm, double[] matrix2) + { + int i, ii, ip, j, k; + int rp; + int cv, rv; + + // rp = row_perm; + rp = 0; + + // For each column vector of matrix2 ... + for (k = 0; k < 3; k++) + { + // cv = &(matrix2[0][k]); + cv = k; + ii = -1; + + // Forward substitution + for (i = 0; i < 3; i++) + { + double sum; + + ip = row_perm[rp + i]; + sum = matrix2[cv + 3 * ip]; + matrix2[cv + 3 * ip] = matrix2[cv + 3 * i]; + if (ii >= 0) + { + // rv = &(matrix1[i][0]); + rv = i * 3; + for (j = ii; j <= i - 1; j++) + { + sum -= matrix1[rv + j] * matrix2[cv + 3 * j]; + } + } + else if (sum != 0.0) + { + ii = i; + } + matrix2[cv + 3 * i] = sum; + } + + // Backsubstitution + // rv = &(matrix1[3][0]); + rv = 2 * 3; + matrix2[cv + 3 * 2] /= matrix1[rv + 2]; + + rv -= 3; + matrix2[cv + 3 * 1] = (matrix2[cv + 3 * 1] - matrix1[rv + 2] * matrix2[cv + 3 * 2]) / matrix1[rv + 1]; + + rv -= 3; + matrix2[cv + 4 * 0] = (matrix2[cv + 3 * 0] - matrix1[rv + 1] * matrix2[cv + 3 * 1] - matrix1[rv + 2] * matrix2[cv + 3 * 2]) + / matrix1[rv + 0]; + + } + } + + double result4[] = new double[16]; + int row_perm4[] = new int[4]; + double[] tmp4 = new double[16]; // scratch matrix + + final void invertGeneral4(Matrix4d thisM, Matrix4d m1) + { + for (int i = 0; i < 4; i++) + row_perm4[i] = 0; + + for (int i = 0; i < 16; i++) + result4[i] = 0.0; + + // Use LU decomposition and backsubstitution code specifically + // for floating-point 4x4 matrices. + + // Copy source matrix to t1tmp + tmp4[0] = m1.m00; + tmp4[1] = m1.m01; + tmp4[2] = m1.m02; + tmp4[3] = m1.m03; + + tmp4[4] = m1.m10; + tmp4[5] = m1.m11; + tmp4[6] = m1.m12; + tmp4[7] = m1.m13; + + tmp4[8] = m1.m20; + tmp4[9] = m1.m21; + tmp4[10] = m1.m22; + tmp4[11] = m1.m23; + + tmp4[12] = m1.m30; + tmp4[13] = m1.m31; + tmp4[14] = m1.m32; + tmp4[15] = m1.m33; + + // Calculate LU decomposition: Is the matrix singular? + if (!luDecomposition4(tmp4, row_perm4)) + { + // Matrix has no inverse + throw new SingularMatrixException("luDecomposition4(tmp4, row_perm4)"); + } + + // Perform back substitution on the identity matrix + result4[0] = 1.0; + result4[5] = 1.0; + result4[10] = 1.0; + result4[15] = 1.0; + luBacksubstitution4(tmp4, row_perm4, result4); + + thisM.m00 = result4[0]; + thisM.m01 = result4[1]; + thisM.m02 = result4[2]; + thisM.m03 = result4[3]; + + thisM.m10 = result4[4]; + thisM.m11 = result4[5]; + thisM.m12 = result4[6]; + thisM.m13 = result4[7]; + + thisM.m20 = result4[8]; + thisM.m21 = result4[9]; + thisM.m22 = result4[10]; + thisM.m23 = result4[11]; + + thisM.m30 = result4[12]; + thisM.m31 = result4[13]; + thisM.m32 = result4[14]; + thisM.m33 = result4[15]; + + } + + double row_scale4[] = new double[4]; + + boolean luDecomposition4(double[] matrix0, int[] row_perm) + { + for (int i = 0; i < 4; i++) + row_scale4[i] = 0.0; + // Determine implicit scaling information by looping over rows + { + int i, j; + int ptr, rs; + double big, temp; + + ptr = 0; + rs = 0; + + // For each row ... + i = 4; + while (i-- != 0) + { + big = 0.0; + + // For each column, find the largest element in the row + j = 4; + while (j-- != 0) + { + temp = matrix0[ptr++]; + temp = Math.abs(temp); + if (temp > big) + { + big = temp; + } + } + + // Is the matrix singular? + if (big == 0.0) + { + return false; + } + row_scale4[rs++] = 1.0 / big; + } + } + + { + int j; + int mtx; + + mtx = 0; + + // For all columns, execute Crout's method + for (j = 0; j < 4; j++) + { + int i, imax, k; + int target, p1, p2; + double sum, big, temp; + + // Determine elements of upper diagonal matrix U + for (i = 0; i < j; i++) + { + target = mtx + (4 * i) + j; + sum = matrix0[target]; + k = i; + p1 = mtx + (4 * i); + p2 = mtx + j; + while (k-- != 0) + { + sum -= matrix0[p1] * matrix0[p2]; + p1++; + p2 += 4; + } + matrix0[target] = sum; + } + + // Search for largest pivot element and calculate + // intermediate elements of lower diagonal matrix L. + big = 0.0; + imax = -1; + for (i = j; i < 4; i++) + { + target = mtx + (4 * i) + j; + sum = matrix0[target]; + k = j; + p1 = mtx + (4 * i); + p2 = mtx + j; + while (k-- != 0) + { + sum -= matrix0[p1] * matrix0[p2]; + p1++; + p2 += 4; + } + matrix0[target] = sum; + + // Is this the best pivot so far? + if ((temp = row_scale4[i] * Math.abs(sum)) >= big) + { + big = temp; + imax = i; + } + } + + if (imax < 0) + { + throw new RuntimeException("(imax < 0)"); + } + + // Is a row exchange necessary? + if (j != imax) + { + // Yes: exchange rows + k = 4; + p1 = mtx + (4 * imax); + p2 = mtx + (4 * j); + while (k-- != 0) + { + temp = matrix0[p1]; + matrix0[p1++] = matrix0[p2]; + matrix0[p2++] = temp; + } + + // Record change in scale factor + row_scale4[imax] = row_scale4[j]; + } + + // Record row permutation + row_perm[j] = imax; + + // Is the matrix singular + if (matrix0[(mtx + (4 * j) + j)] == 0.0) + { + return false; + } + + // Divide elements of lower diagonal matrix L by pivot + if (j != (4 - 1)) + { + temp = 1.0 / (matrix0[(mtx + (4 * j) + j)]); + target = mtx + (4 * (j + 1)) + j; + i = 3 - j; + while (i-- != 0) + { + matrix0[target] *= temp; + target += 4; + } + } + } + } + + return true; + } + + void luBacksubstitution4(double[] matrix1, int[] row_perm, double[] matrix2) + { + + int i, ii, ip, j, k; + int rp; + int cv, rv; + + // rp = row_perm; + rp = 0; + + // For each column vector of matrix2 ... + for (k = 0; k < 4; k++) + { + // cv = &(matrix2[0][k]); + cv = k; + ii = -1; + + // Forward substitution + for (i = 0; i < 4; i++) + { + double sum; + + ip = row_perm[rp + i]; + sum = matrix2[cv + 4 * ip]; + matrix2[cv + 4 * ip] = matrix2[cv + 4 * i]; + if (ii >= 0) + { + // rv = &(matrix1[i][0]); + rv = i * 4; + for (j = ii; j <= i - 1; j++) + { + sum -= matrix1[rv + j] * matrix2[cv + 4 * j]; + } + } + else if (sum != 0.0) + { + ii = i; + } + matrix2[cv + 4 * i] = sum; + } + + // Backsubstitution + // rv = &(matrix1[3][0]); + rv = 3 * 4; + matrix2[cv + 4 * 3] /= matrix1[rv + 3]; + + rv -= 4; + matrix2[cv + 4 * 2] = (matrix2[cv + 4 * 2] - matrix1[rv + 3] * matrix2[cv + 4 * 3]) / matrix1[rv + 2]; + + rv -= 4; + matrix2[cv + 4 * 1] = (matrix2[cv + 4 * 1] - matrix1[rv + 2] * matrix2[cv + 4 * 2] - matrix1[rv + 3] * matrix2[cv + 4 * 3]) + / matrix1[rv + 1]; + + rv -= 4; + matrix2[cv + 4 * 0] = (matrix2[cv + 4 * 0] - matrix1[rv + 1] * matrix2[cv + 4 * 1] - matrix1[rv + 2] * matrix2[cv + 4 * 2] + - matrix1[rv + 3] * matrix2[cv + 4 * 3]) / matrix1[rv + 0]; + } + } + + public final void transform(Matrix4d m, Tuple4f vecOut) + { + float x, y, z; + + x = (float) (m.m00 * vecOut.x + m.m01 * vecOut.y + m.m02 * vecOut.z + m.m03 * vecOut.w); + y = (float) (m.m10 * vecOut.x + m.m11 * vecOut.y + m.m12 * vecOut.z + m.m13 * vecOut.w); + z = (float) (m.m20 * vecOut.x + m.m21 * vecOut.y + m.m22 * vecOut.z + m.m23 * vecOut.w); + vecOut.w = (float) (m.m30 * vecOut.x + m.m31 * vecOut.y + m.m32 * vecOut.z + m.m33 * vecOut.w); + vecOut.x = x; + vecOut.y = y; + vecOut.z = z; + } + + //Oh lordy lordy yo' betta swear yo' single freadin' !!! + + public double[] deburnV2 = null;//deburners + + public Matrix4d deburnV = new Matrix4d();//deburners + public Matrix4d deburnM = new Matrix4d(); + public float[] tempMat9 = new float[9]; + public float[] tempMat12 = new float[12]; + public float[] tempMat16 = new float[16]; + public double[] tempMatD9 = new double[9]; + + public float[] toArray(Matrix4d m) + { + tempMat16[0] = (float) m.m00; + tempMat16[1] = (float) m.m01; + tempMat16[2] = (float) m.m02; + tempMat16[3] = (float) m.m03; + tempMat16[4] = (float) m.m10; + tempMat16[5] = (float) m.m11; + tempMat16[6] = (float) m.m12; + tempMat16[7] = (float) m.m13; + tempMat16[8] = (float) m.m20; + tempMat16[9] = (float) m.m21; + tempMat16[10] = (float) m.m22; + tempMat16[11] = (float) m.m23; + tempMat16[12] = (float) m.m30; + tempMat16[13] = (float) m.m31; + tempMat16[14] = (float) m.m32; + tempMat16[15] = (float) m.m33; + return tempMat16; + } + + public static float[] toArray(Matrix4d m, float[] a) + { + a[0] = (float) m.m00; + a[1] = (float) m.m01; + a[2] = (float) m.m02; + a[3] = (float) m.m03; + a[4] = (float) m.m10; + a[5] = (float) m.m11; + a[6] = (float) m.m12; + a[7] = (float) m.m13; + a[8] = (float) m.m20; + a[9] = (float) m.m21; + a[10] = (float) m.m22; + a[11] = (float) m.m23; + a[12] = (float) m.m30; + a[13] = (float) m.m31; + a[14] = (float) m.m32; + a[15] = (float) m.m33; + + return a; + } + + public float[] toArray(Matrix3d m) + { + tempMat9[0] = (float) m.m00; + tempMat9[1] = (float) m.m01; + tempMat9[2] = (float) m.m02; + tempMat9[3] = (float) m.m10; + tempMat9[4] = (float) m.m11; + tempMat9[5] = (float) m.m12; + tempMat9[6] = (float) m.m20; + tempMat9[7] = (float) m.m21; + tempMat9[8] = (float) m.m22; + return tempMat9; + + } + + public static float[] toArray(Matrix3d m, float[] a) + { + a[0] = (float) m.m00; + a[1] = (float) m.m01; + a[2] = (float) m.m02; + a[3] = (float) m.m10; + a[4] = (float) m.m11; + a[5] = (float) m.m12; + a[6] = (float) m.m20; + a[7] = (float) m.m21; + a[8] = (float) m.m22; + + return a; + } + + public float[] toArray3x4(Matrix3d m) + { + return toArray3x4(m, tempMat12); + } + + public static float[] toArray3x4(Matrix3d m, float[] a) + { + a[0] = (float) m.m00; + a[1] = (float) m.m01; + a[2] = (float) m.m02; + a[3] = 0f; + a[4] = (float) m.m10; + a[5] = (float) m.m11; + a[6] = (float) m.m12; + a[7] = 0f; + a[8] = (float) m.m20; + a[9] = (float) m.m21; + a[10] = (float) m.m22; + a[11] = 0f; + + return a; + } + + public double[] toArray3x3(Matrix4d m) + { + return toArray3x3(m, tempMatD9); + } + + public static double[] toArray3x3(Matrix4d m, double[] a) + { + a[0] = m.m00; + a[1] = m.m01; + a[2] = m.m02; + a[3] = m.m10; + a[4] = m.m11; + a[5] = m.m12; + a[6] = m.m20; + a[7] = m.m21; + a[8] = m.m22; + + return a; + } + + public void invert(Matrix3d m1) + { + try + { + invertGeneral3(m1, m1); + } + catch (Exception e) + { + //fine, move along + m1.setIdentity(); + } + } + + public void invert(Matrix4d m1) + { + try + { + invertGeneral4(m1, m1); + } + catch (Exception e) + { + //fine, move along + m1.setIdentity(); + } + } + + //More single threaded death-defying gear + private Vector4f tmpV4f = new Vector4f();; + + public Vector4f transform(Matrix4d m1, Matrix4d m2, float tx, float ty, float tz, float tw) + { + tmpV4f.set(tx, ty, tz, tw); + transform(m1, tmpV4f); + transform(m2, tmpV4f); + return tmpV4f; + } + + private FloatBuffer matFB4x4; + + public FloatBuffer toFB4(float[] f) + { + if (matFB4x4 == null) + { + ByteBuffer bb = ByteBuffer.allocateDirect(16 * 4); + bb.order(ByteOrder.nativeOrder()); + matFB4x4 = bb.asFloatBuffer(); + } + matFB4x4.position(0); + matFB4x4.put(f); + matFB4x4.position(0); + return matFB4x4; + } + + public FloatBuffer toFB3(float[] f) + { + if (matFB3x3 == null) + { + ByteBuffer bb = ByteBuffer.allocateDirect(16 * 4); + bb.order(ByteOrder.nativeOrder()); + matFB3x3 = bb.asFloatBuffer(); + } + matFB3x3.position(0); + matFB3x3.put(f); + matFB3x3.position(0); + return matFB3x3; + } + + public FloatBuffer toFB(Matrix4d m) + { + if (matFB4x4 == null) + { + ByteBuffer bb = ByteBuffer.allocateDirect(16 * 4); + bb.order(ByteOrder.nativeOrder()); + matFB4x4 = bb.asFloatBuffer(); + } + matFB4x4.position(0); + matFB4x4.put(toArray(m)); + matFB4x4.position(0); + return matFB4x4; + } + + private FloatBuffer matFB3x3; + + public FloatBuffer toFB(Matrix3d m) + { + if (matFB3x3 == null) + { + ByteBuffer bb = ByteBuffer.allocateDirect(9 * 4); + bb.order(ByteOrder.nativeOrder()); + matFB3x3 = bb.asFloatBuffer(); + } + matFB3x3.position(0); + matFB3x3.put(toArray(m)); + matFB3x3.position(0); + return matFB3x3; + } + + public static float[] transposeInPlace(float[] src) + { + if (src.length == 9) + { + float temp; + + temp = src[3]; + src[3] = src[1]; + src[1] = temp; + + temp = src[6]; + src[6] = src[2]; + src[2] = temp; + + temp = src[7]; + src[7] = src[5]; + src[5] = temp; + + } + else if (src.length == 16) + { + float v1 = src[1]; + float v2 = src[2]; + float v3 = src[3]; + float v6 = src[6]; + float v7 = src[7]; + float v11 = src[11]; + + //src[0] = src[0]; + src[1] = src[4]; + src[2] = src[8]; + src[3] = src[12]; + src[4] = v1; + //src[5] = src[5]; + src[6] = src[9]; + src[7] = src[13]; + src[8] = v2; + src[9] = v6; + //src[10] = src[10]; + src[11] = src[14]; + src[12] = v3; + src[13] = v7; + src[14] = v11; + //src[15] = src[15]; + } + else + { + throw new UnsupportedOperationException("Only 9 or 16 length float arrays can be transposed!"); + } + return src; + + } + + // ignores the higher 16 bits + public static float halfToFloat(int hbits) + { + int mant = hbits & 0x03ff; // 10 bits mantissa + int exp = hbits & 0x7c00; // 5 bits exponent + if (exp == 0x7c00) // NaN/Inf + exp = 0x3fc00; // -> NaN/Inf + else if (exp != 0) // normalized value + { + exp += 0x1c000; // exp - 15 + 127 + if (mant == 0 && exp > 0x1c400) // smooth transition + return Float.intBitsToFloat((hbits & 0x8000) << 16 | exp << 13 | 0x3ff); + } + else if (mant != 0) // && exp==0 -> subnormal + { + exp = 0x1c400; // make it normal + do + { + mant <<= 1; // mantissa * 2 + exp -= 0x400; // decrease exp by 1 + } + while ((mant & 0x400) == 0); // while not normal + mant &= 0x3ff; // discard subnormal bit + } // else +/-0 -> +/-0 + return Float.intBitsToFloat( // combine all parts + (hbits & 0x8000) << 16 // sign << ( 31 - 15 ) + | (exp | mant) << 13); // value << ( 23 - 10 ) + } + + // returns all higher 16 bits as 0 for all results + public static int halfFromFloat(float fval) + { + int fbits = Float.floatToIntBits(fval); + int sign = fbits >>> 16 & 0x8000; // sign only + int val = (fbits & 0x7fffffff) + 0x1000; // rounded value + + if (val >= 0x47800000) // might be or become NaN/Inf + { // avoid Inf due to rounding + if ((fbits & 0x7fffffff) >= 0x47800000) + { // is or must become NaN/Inf + if (val < 0x7f800000) // was value but too large + return sign | 0x7c00; // make it +/-Inf + return sign | 0x7c00 | // remains +/-Inf or NaN + (fbits & 0x007fffff) >>> 13; // keep NaN (and Inf) bits + } + return sign | 0x7bff; // unrounded not quite Inf + } + if (val >= 0x38800000) // remains normalized value + return sign | val - 0x38000000 >>> 13; // exp - 127 + 15 + if (val < 0x33000000) // too small for subnormal + return sign; // becomes +/-0 + val = (fbits & 0x7fffffff) >>> 23; // tmp exp for subnormal calc + return sign | ((fbits & 0x7fffff | 0x800000) // add subnormal bit + + (0x800000 >>> val - 102) // round depending on cut off + >>> 126 - val); // div by 2^(1-(exp-127+15)) and >> 13 | exp=0 + } }
\ No newline at end of file diff --git a/src/main/java/org/jogamp/java3d/Jogl2es2Pipeline.java b/src/main/java/org/jogamp/java3d/Jogl2es2Pipeline.java index a3311a2..433bb7c 100644 --- a/src/main/java/org/jogamp/java3d/Jogl2es2Pipeline.java +++ b/src/main/java/org/jogamp/java3d/Jogl2es2Pipeline.java @@ -2932,7 +2932,12 @@ class Jogl2es2Pipeline extends Jogl2es2DEPPipeline { if (!MINIMISE_NATIVE_CALLS_FFP || (shaderProgramId != ctx.prevShaderProgram)) { - gl.glUniformMatrix4fv(locs.glProjectionMatrix, 1, true, ctx.matrixUtil.toArray(ctx.currentProjMat), 0); + if (gl.isGL2ES3()) + gl.glUniformMatrix4fv(locs.glProjectionMatrix, 1, true, ctx.matrixUtil.toArray(ctx.currentProjMat), 0); + else + gl.glUniformMatrix4fv(locs.glProjectionMatrix, 1, false, + Jogl2es2MatrixUtil.transposeInPlace(ctx.matrixUtil.toArray(ctx.currentProjMat)), 0); + if (DO_OUTPUT_ERRORS) outputErrors(ctx); } @@ -2952,7 +2957,11 @@ class Jogl2es2Pipeline extends Jogl2es2DEPPipeline System.err.println("" + e); } - gl.glUniformMatrix4fv(locs.glProjectionMatrixInverse, 1, true, ctx.matrixUtil.toArray(ctx.currentProjMatInverse), 0); + if (gl.isGL2ES3()) + gl.glUniformMatrix4fv(locs.glProjectionMatrixInverse, 1, true, ctx.matrixUtil.toArray(ctx.currentProjMatInverse), 0); + else + gl.glUniformMatrix4fv(locs.glProjectionMatrixInverse, 1, false, + Jogl2es2MatrixUtil.transposeInPlace(ctx.matrixUtil.toArray(ctx.currentProjMatInverse)), 0); if (DO_OUTPUT_ERRORS) outputErrors(ctx); @@ -2973,7 +2982,13 @@ class Jogl2es2Pipeline extends Jogl2es2DEPPipeline if (!MINIMISE_NATIVE_CALLS_FFP || (shaderProgramId != ctx.prevShaderProgram || ctx.gl_state.modelMatrix.m00 == Double.NEGATIVE_INFINITY)) { - gl.glUniformMatrix4fv(locs.glModelMatrix, 1, true, ctx.matrixUtil.toArray(ctx.currentModelMat), 0); + + if (gl.isGL2ES3()) + gl.glUniformMatrix4fv(locs.glModelMatrix, 1, true, ctx.matrixUtil.toArray(ctx.currentModelMat), 0); + else + gl.glUniformMatrix4fv(locs.glModelMatrix, 1, false, + Jogl2es2MatrixUtil.transposeInPlace(ctx.matrixUtil.toArray(ctx.currentModelMat)), 0); + if (DO_OUTPUT_ERRORS) outputErrors(ctx); if (MINIMISE_NATIVE_CALLS_FFP) @@ -2997,7 +3012,12 @@ class Jogl2es2Pipeline extends Jogl2es2DEPPipeline if (ctx.currentModelViewMat.m00 == Double.NEGATIVE_INFINITY) ctx.currentModelViewMat.mul(ctx.currentViewMat, ctx.currentModelMat); - gl.glUniformMatrix4fv(locs.glModelViewMatrix, 1, true, ctx.matrixUtil.toArray(ctx.currentModelViewMat), 0); + if (gl.isGL2ES3()) + gl.glUniformMatrix4fv(locs.glModelViewMatrix, 1, true, ctx.matrixUtil.toArray(ctx.currentModelViewMat), 0); + else + gl.glUniformMatrix4fv(locs.glModelViewMatrix, 1, false, + Jogl2es2MatrixUtil.transposeInPlace(ctx.matrixUtil.toArray(ctx.currentModelViewMat)), 0); + if (DO_OUTPUT_ERRORS) outputErrors(ctx); @@ -3023,8 +3043,13 @@ class Jogl2es2Pipeline extends Jogl2es2DEPPipeline ctx.matrixUtil.invert(ctx.currentModelViewMatInverse); } - //gl.glUniformMatrix4fv(locs.glModelViewMatrixInverse, 1, false, ctx.toFB(ctx.currentModelViewMatInverse)); - gl.glUniformMatrix4fv(locs.glModelViewMatrixInverse, 1, true, ctx.matrixUtil.toArray(ctx.currentModelViewMatInverse), 0); + + if (gl.isGL2ES3()) + gl.glUniformMatrix4fv(locs.glModelViewMatrixInverse, 1, true, ctx.matrixUtil.toArray(ctx.currentModelViewMatInverse), 0); + else + gl.glUniformMatrix4fv(locs.glModelViewMatrixInverse, 1, false, + Jogl2es2MatrixUtil.transposeInPlace(ctx.matrixUtil.toArray(ctx.currentModelViewMatInverse)), 0); + if (DO_OUTPUT_ERRORS) outputErrors(ctx); @@ -3050,8 +3075,12 @@ class Jogl2es2Pipeline extends Jogl2es2DEPPipeline if (ctx.currentModelViewProjMat.m00 == Double.NEGATIVE_INFINITY) ctx.currentModelViewProjMat.mul(ctx.currentProjMat, ctx.currentModelViewMat); - //gl.glUniformMatrix4fv(locs.glModelViewProjectionMatrix, 1, false, ctx.toFB(ctx.currentModelViewProjMat)); - gl.glUniformMatrix4fv(locs.glModelViewProjectionMatrix, 1, true, ctx.matrixUtil.toArray(ctx.currentModelViewProjMat), 0); + if (gl.isGL2ES3()) + gl.glUniformMatrix4fv(locs.glModelViewProjectionMatrix, 1, true, ctx.matrixUtil.toArray(ctx.currentModelViewProjMat), 0); + else + gl.glUniformMatrix4fv(locs.glModelViewProjectionMatrix, 1, false, + Jogl2es2MatrixUtil.transposeInPlace(ctx.matrixUtil.toArray(ctx.currentModelViewProjMat)), 0); + if (DO_OUTPUT_ERRORS) outputErrors(ctx); @@ -3078,8 +3107,12 @@ class Jogl2es2Pipeline extends Jogl2es2DEPPipeline if (ctx.currentNormalMat.m00 == Double.NEGATIVE_INFINITY) Jogl2es2MatrixUtil.transposeInvert(ctx.currentModelViewMat, ctx.currentNormalMat); - //gl.glUniformMatrix3fv(locs.glNormalMatrix, 1, false, ctx.toFB(ctx.currentNormalMat)); - gl.glUniformMatrix3fv(locs.glNormalMatrix, 1, true, ctx.matrixUtil.toArray(ctx.currentNormalMat), 0); + if (gl.isGL2ES3()) + gl.glUniformMatrix3fv(locs.glNormalMatrix, 1, true, ctx.matrixUtil.toArray(ctx.currentNormalMat), 0); + else + gl.glUniformMatrix3fv(locs.glNormalMatrix, 1, false, + Jogl2es2MatrixUtil.transposeInPlace(ctx.matrixUtil.toArray(ctx.currentNormalMat)), 0); + if (DO_OUTPUT_ERRORS) outputErrors(ctx); if (MINIMISE_NATIVE_CALLS_FFP) @@ -5744,9 +5777,10 @@ class Jogl2es2Pipeline extends Jogl2es2DEPPipeline // gl.glTexParameteri(target, GL2ES3.GL_TEXTURE_BASE_LEVEL, baseLevel); // http://stackoverflow.com/questions/12767917/is-using-gl-nearest-mipmap-or-gl-linear-mipmap-for-gl-texture-min-filter-con - // so hopefully ES2 just assumes the mip maps given are correct and ignores this call + // ES2 throws a 1280 invalid enum here - gl.glTexParameteri(target, GL2ES3.GL_TEXTURE_MAX_LEVEL, maximumLevel); + if (gl.isGL2ES3()) + gl.glTexParameteri(target, GL2ES3.GL_TEXTURE_MAX_LEVEL, maximumLevel); // gl.glTexParameterf(target, GL2ES3.GL_TEXTURE_MIN_LOD, minimumLOD); // gl.glTexParameterf(target, GL2ES3.GL_TEXTURE_MAX_LOD, maximumLOD); |