aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2023-09-20 19:51:55 +0200
committerSven Gothel <[email protected]>2023-09-20 19:51:55 +0200
commit5d6e8a367c03644740187e500c6de5d3ac039d5e (patch)
treea649f559413c51272ee3f4afff1f68ebfea45477 /src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java
parentbbe845846ffc00807395a5070a7352c6bbe7e4ef (diff)
Bug 1452 - Decouple math functionality to 'com.jogamp.math' to be toolkit agnostic (PMVMatrix, Matrix4f, Vec4f, ..)
Math functionality (PMVMatrix, Matrix4f, Vec4f, ..) - shall be used toolkit agnostic, e.g. independent from OpenGL - shall be reused within our upcoming Vulkan implementation - may also move outside of JOGL, i.e. GlueGen or within its own package to be reused for other purposed. The 'com.jogamp.opengl.util.PMVMatrix' currently also used to feed in GLUniformData via the toolkit agnostic SyncAction and SyncBuffer shall also be split to a toolkit agnostic variant. An OpenGL PMVMatrix specialization implementing GLMatrixFunc can still exist, being derived from the toolkit agnostic base implementation. +++ Initial commit .. compile clean, passing most unit tests.
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java1628
1 files changed, 0 insertions, 1628 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java b/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java
deleted file mode 100644
index 25b5a8ad7..000000000
--- a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java
+++ /dev/null
@@ -1,1628 +0,0 @@
-/**
- * Copyright 2010-2023 JogAmp Community. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are
- * permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice, this list
- * of conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are those of the
- * authors and should not be interpreted as representing official policies, either expressed
- * or implied, of JogAmp Community.
- */
-package com.jogamp.opengl.math;
-
-import java.nio.FloatBuffer;
-import java.util.Locale;
-
-import com.jogamp.opengl.GLException;
-
-import jogamp.opengl.Debug;
-
-import com.jogamp.common.os.Platform;
-
-/**
- * Basic Float math utility functions.
- * <p>
- * Implementation assumes linear matrix layout in column-major order
- * matching OpenGL's implementation, illustration:
- * <pre>
- Row-Major Column-Major (OpenGL):
-
- | 0 1 2 tx |
- | |
- | 4 5 6 ty |
- M = | |
- | 8 9 10 tz |
- | |
- | 12 13 14 15 |
-
- R C R C
- m[0*4+3] = tx; m[0+4*3] = tx;
- m[1*4+3] = ty; m[1+4*3] = ty;
- m[2*4+3] = tz; m[2+4*3] = tz;
-
- RC (std subscript order) RC (std subscript order)
- m03 = tx; m03 = tx;
- m13 = ty; m13 = ty;
- m23 = tz; m23 = tz;
-
- * </pre>
- * </p>
- * <p>
- * <ul>
- * <li><a href="http://web.archive.org/web/20041029003853/http://www.j3d.org/matrix_faq/matrfaq_latest.html">Matrix-FAQ</a></li>
- * <li><a href="https://en.wikipedia.org/wiki/Matrix_%28mathematics%29">Wikipedia-Matrix</a></li>
- * <li><a href="http://www.euclideanspace.com/maths/algebra/matrix/index.htm">euclideanspace.com-Matrix</a></li>
- * </ul>
- * </p>
- * <p>
- * Implementation utilizes unrolling of small vertices and matrices wherever possible
- * while trying to access memory in a linear fashion for performance reasons, see:
- * <ul>
- * <li><a href="https://lessthanoptimal.github.io/Java-Matrix-Benchmark/">java-matrix-benchmark</a></li>
- * <li><a href="https://github.com/lessthanoptimal/ejml">EJML Efficient Java Matrix Library</a></li>
- * </ul>
- * </p>
- */
-public final class FloatUtil {
- public static final boolean DEBUG = Debug.debugExplicit("Math");
-
- //
- // Matrix Ops
- // Only a subset will remain here, try using Matrix4f and perhaps PMVMatrix, SyncMatrix4f16 or SyncMatrices4f16
- //
-
- /**
- * Make matrix an identity matrix
- * @param m 4x4 matrix in column-major order (also result)
- * @return given matrix for chaining
- */
- public static float[] makeIdentity(final float[] m) {
- m[0+4*0] = 1f;
- m[1+4*0] = 0f;
- m[2+4*0] = 0f;
- m[3+4*0] = 0f;
-
- m[0+4*1] = 0f;
- m[1+4*1] = 1f;
- m[2+4*1] = 0f;
- m[3+4*1] = 0f;
-
- m[0+4*2] = 0f;
- m[1+4*2] = 0f;
- m[2+4*2] = 1f;
- m[3+4*2] = 0f;
-
- m[0+4*3] = 0f;
- m[1+4*3] = 0f;
- m[2+4*3] = 0f;
- m[3+4*3] = 1f;
- return m;
- }
-
- /**
- * Make a translation matrix in column-major order from the given axis deltas
- * <pre>
- Translation matrix (Column Order):
- 1 0 0 0
- 0 1 0 0
- 0 0 1 0
- x y z 1
- * </pre>
- * <p>
- * All matrix fields are only set if <code>initM</code> is <code>true</code>.
- * </p>
- * @param m 4x4 matrix in column-major order (also result)
- * @param initM if true, given matrix will be initialized w/ identity matrix,
- * otherwise only the diagonal and last-row is set.
- * The latter can be utilized to share a once {@link #makeIdentity(float[], int) identity set} matrix
- * for {@link #makeScale(float[], int, boolean, float, float, float) scaling}
- * and {@link #makeTranslation(float[], int, boolean, float, float, float) translation},
- * while leaving the other fields untouched for performance reasons.
- * @return given matrix for chaining
- */
- public static float[] makeTranslation(final float[] m, final boolean initM, final float tx, final float ty, final float tz) {
- if( initM ) {
- makeIdentity(m);
- } else {
- m[0+4*0] = 1;
- m[1+4*1] = 1;
- m[2+4*2] = 1;
- m[3+4*3] = 1;
- }
- m[0+4*3] = tx;
- m[1+4*3] = ty;
- m[2+4*3] = tz;
- return m;
- }
-
- /**
- * Make a scale matrix in column-major order from the given axis factors
- * <pre>
- Scale matrix (Any Order):
- x 0 0 0
- 0 y 0 0
- 0 0 z 0
- 0 0 0 1
- * </pre>
- * <p>
- * All matrix fields are only set if <code>initM</code> is <code>true</code>.
- * </p>
- * @param m 4x4 matrix in column-major order (also result)
- * @param initM if true, given matrix will be initialized w/ identity matrix,
- * otherwise only the diagonal and last-row is set.
- * The latter can be utilized to share a once {@link #makeIdentity(float[], int) identity set} matrix
- * for {@link #makeScale(float[], int, boolean, float, float, float) scaling}
- * and {@link #makeTranslation(float[], int, boolean, float, float, float) translation},
- * while leaving the other fields untouched for performance reasons.
- * @return given matrix for chaining
- */
- public static float[] makeScale(final float[] m, final boolean initM, final float sx, final float sy, final float sz) {
- if( initM ) {
- makeIdentity(m);
- } else {
- m[0+4*3] = 0;
- m[1+4*3] = 0;
- m[2+4*3] = 0;
- m[3+4*3] = 1;
- }
- m[0+4*0] = sx;
- m[1+4*1] = sy;
- m[2+4*2] = sz;
- return m;
- }
-
- /**
- * Make given matrix the frustum matrix based on given parameters.
- * <pre>
- Frustum matrix (Column Order):
- 2*zNear/dx 0 0 0
- 0 2*zNear/dy 0 0
- A B C -1
- 0 0 D 0
- * </pre>
- * <p>
- * All matrix fields are only set if <code>initM</code> is <code>true</code>.
- * </p>
- *
- * @param m 4x4 matrix in column-major order (also result)
- * @param m_offset offset in given array <i>m</i>, i.e. start of the 4x4 matrix
- * @param initM if true, given matrix will be initialized w/ identity matrix,
- * otherwise only the frustum fields are set.
- * @param left
- * @param right
- * @param bottom
- * @param top
- * @param zNear
- * @param zFar
- * @return given matrix for chaining
- * @throws GLException if {@code zNear <= 0} or {@code zFar <= zNear}
- * or {@code left == right}, or {@code bottom == top}.
- */
- public static float[] makeFrustum(final float[] m, final int m_offset, final boolean initM,
- final float left, final float right,
- final float bottom, final float top,
- final float zNear, final float zFar) throws GLException {
- if( zNear <= 0.0f || zFar <= zNear ) {
- throw new GLException("Requirements zNear > 0 and zFar > zNear, but zNear "+zNear+", zFar "+zFar);
- }
- if( left == right || top == bottom) {
- throw new GLException("GL_INVALID_VALUE: top,bottom and left,right must not be equal");
- }
- if( initM ) {
- // m[m_offset+0+4*0] = 1f;
- m[m_offset+1+4*0] = 0f;
- m[m_offset+2+4*0] = 0f;
- m[m_offset+3+4*0] = 0f;
-
- m[m_offset+0+4*1] = 0f;
- // m[m_offset+1+4*1] = 1f;
- m[m_offset+2+4*1] = 0f;
- m[m_offset+3+4*1] = 0f;
-
- // m[m_offset+0+4*2] = 0f;
- // m[m_offset+1+4*2] = 0f;
- // m[m_offset+2+4*2] = 1f;
- // m[m_offset+3+4*2] = 0f;
-
- m[m_offset+0+4*3] = 0f;
- m[m_offset+1+4*3] = 0f;
- // m[m_offset+2+4*3] = 0f;
- // m[m_offset+3+4*3] = 1f;
- }
- final float zNear2 = 2.0f*zNear;
- final float dx=right-left;
- final float dy=top-bottom;
- final float dz=zFar-zNear;
- final float A=(right+left)/dx;
- final float B=(top+bottom)/dy;
- final float C=-1.0f*(zFar+zNear)/dz;
- final float D=-2.0f*(zFar*zNear)/dz;
-
- m[m_offset+0+4*0] = zNear2/dx;
-
- m[m_offset+1+4*1] = zNear2/dy;
-
- m[m_offset+0+4*2] = A;
- m[m_offset+1+4*2] = B;
- m[m_offset+2+4*2] = C;
- m[m_offset+3+4*2] = -1.0f;
-
- m[m_offset+2+4*3] = D;
- m[m_offset+3+4*3] = 0f;
-
- return m;
- }
-
- /**
- * Make given matrix the perspective {@link #makeFrustum(float[], int, boolean, float, float, float, float, float, float) frustum}
- * matrix based on given parameters.
- * <p>
- * All matrix fields are only set if <code>initM</code> is <code>true</code>.
- * </p>
- *
- * @param m 4x4 matrix in column-major order (also result)
- * @param m_offset offset in given array <i>m</i>, i.e. start of the 4x4 matrix
- * @param initM if true, given matrix will be initialized w/ identity matrix,
- * otherwise only the frustum fields are set.
- * @param fovy_rad angle in radians
- * @param aspect aspect ratio width / height
- * @param zNear
- * @param zFar
- * @return given matrix for chaining
- * @throws GLException if {@code zNear <= 0} or {@code zFar <= zNear}
- * @see #makeFrustum(float[], int, boolean, float, float, float, float, float, float)
- */
- public static float[] makePerspective(final float[] m, final int m_off, final boolean initM,
- final float fovy_rad, final float aspect, final float zNear, final float zFar) throws GLException {
- final float top = tan(fovy_rad/2f) * zNear; // use tangent of half-fov !
- final float bottom = -1.0f * top; // -1f * fovhvTan.top * zNear
- final float left = aspect * bottom; // aspect * -1f * fovhvTan.top * zNear
- final float right = aspect * top; // aspect * fovhvTan.top * zNear
- return makeFrustum(m, m_off, initM, left, right, bottom, top, zNear, zFar);
- }
-
- /**
- * Make given matrix the <i>look-at</i> matrix based on given parameters.
- * <p>
- * Consist out of two matrix multiplications:
- * <pre>
- * <b>R</b> = <b>L</b> x <b>T</b>,
- * with <b>L</b> for <i>look-at</i> matrix and
- * <b>T</b> for eye translation.
- *
- * Result <b>R</b> can be utilized for <i>modelview</i> multiplication, i.e.
- * <b>M</b> = <b>M</b> x <b>R</b>,
- * with <b>M</b> being the <i>modelview</i> matrix.
- * </pre>
- * </p>
- * <p>
- * All matrix fields are set.
- * </p>
- * @param m 4x4 matrix in column-major order, result only
- * @param m_offset offset in given array <i>m</i>, i.e. start of the 4x4 matrix
- * @param eye 3 component eye vector
- * @param eye_offset
- * @param center 3 component center vector
- * @param center_offset
- * @param up 3 component up vector
- * @param up_offset
- * @param mat4Tmp temp float[16] storage
- * @return given matrix <code>m</code> for chaining
- */
- public static float[] makeLookAt(final float[] m, final int m_offset,
- final float[] eye, final int eye_offset,
- final float[] center, final int center_offset,
- final float[] up, final int up_offset,
- final float[] mat4Tmp) {
- final int forward_off = 0;
- final int side_off = 3;
- final int up2_off = 6;
-
- // forward!
- mat4Tmp[0] = center[0+center_offset] - eye[0+eye_offset];
- mat4Tmp[1] = center[1+center_offset] - eye[1+eye_offset];
- mat4Tmp[2] = center[2+center_offset] - eye[2+eye_offset];
-
- VectorUtil.normalizeVec3(mat4Tmp); // normalize forward
-
- /* Side = forward x up */
- VectorUtil.crossVec3(mat4Tmp, side_off, mat4Tmp, forward_off, up, up_offset);
- VectorUtil.normalizeVec3(mat4Tmp, side_off); // normalize side
-
- /* Recompute up as: up = side x forward */
- VectorUtil.crossVec3(mat4Tmp, up2_off, mat4Tmp, side_off, mat4Tmp, forward_off);
-
- m[m_offset + 0 * 4 + 0] = mat4Tmp[0+side_off]; // side
- m[m_offset + 0 * 4 + 1] = mat4Tmp[0+up2_off]; // up2
- m[m_offset + 0 * 4 + 2] = -mat4Tmp[0]; // forward
- m[m_offset + 0 * 4 + 3] = 0;
-
- m[m_offset + 1 * 4 + 0] = mat4Tmp[1+side_off]; // side
- m[m_offset + 1 * 4 + 1] = mat4Tmp[1+up2_off]; // up2
- m[m_offset + 1 * 4 + 2] = -mat4Tmp[1]; // forward
- m[m_offset + 1 * 4 + 3] = 0;
-
- m[m_offset + 2 * 4 + 0] = mat4Tmp[2+side_off]; // side
- m[m_offset + 2 * 4 + 1] = mat4Tmp[2+up2_off]; // up2
- m[m_offset + 2 * 4 + 2] = -mat4Tmp[2]; // forward
- m[m_offset + 2 * 4 + 3] = 0;
-
- m[m_offset + 3 * 4 + 0] = 0;
- m[m_offset + 3 * 4 + 1] = 0;
- m[m_offset + 3 * 4 + 2] = 0;
- m[m_offset + 3 * 4 + 3] = 1;
-
- makeTranslation(mat4Tmp, true, -eye[0+eye_offset], -eye[1+eye_offset], -eye[2+eye_offset]);
- multMatrix(m, m_offset, mat4Tmp, 0);
-
- return m;
- }
-
- /**
- * Make given matrix the <i>pick</i> matrix based on given parameters.
- * <p>
- * Traditional <code>gluPickMatrix</code> implementation.
- * </p>
- * <p>
- * Consist out of two matrix multiplications:
- * <pre>
- * <b>R</b> = <b>T</b> x <b>S</b>,
- * with <b>T</b> for viewport translation matrix and
- * <b>S</b> for viewport scale matrix.
- *
- * Result <b>R</b> can be utilized for <i>projection</i> multiplication, i.e.
- * <b>P</b> = <b>P</b> x <b>R</b>,
- * with <b>P</b> being the <i>projection</i> matrix.
- * </pre>
- * </p>
- * <p>
- * To effectively use the generated pick matrix for picking,
- * call {@link #makePick(float[], int, float, float, float, float, int[], int, float[]) makePick}
- * and multiply a {@link #makePerspective(float[], int, boolean, float, float, float, float) custom perspective matrix}
- * by this pick matrix. Then you may load the result onto the perspective matrix stack.
- * </p>
- * <p>
- * All matrix fields are set.
- * </p>
- * @param m 4x4 matrix in column-major order, result only
- * @param m_offset offset in given array <i>m</i>, i.e. start of the 4x4 matrix
- * @param x the center x-component of a picking region in window coordinates
- * @param y the center y-component of a picking region in window coordinates
- * @param deltaX the width of the picking region in window coordinates.
- * @param deltaY the height of the picking region in window coordinates.
- * @param viewport 4 component viewport vector
- * @param viewport_offset
- * @param mat4Tmp temp float[16] storage
- * @return given matrix <code>m</code> for chaining or <code>null</code> if either delta value is <= zero.
- */
- public static float[] makePick(final float[] m,
- final float x, final float y,
- final float deltaX, final float deltaY,
- final int[] viewport, final int viewport_offset,
- final float[] mat4Tmp) {
- if (deltaX <= 0 || deltaY <= 0) {
- return null;
- }
-
- /* Translate and scale the picked region to the entire window */
- makeTranslation(m, true,
- (viewport[2+viewport_offset] - 2 * (x - viewport[0+viewport_offset])) / deltaX,
- (viewport[3+viewport_offset] - 2 * (y - viewport[1+viewport_offset])) / deltaY,
- 0);
- makeScale(mat4Tmp, true,
- viewport[2+viewport_offset] / deltaX, viewport[3+viewport_offset] / deltaY, 1.0f);
- multMatrix(m, mat4Tmp);
- return m;
- }
-
- /**
- * Transpose the given matrix.
- *
- * @param msrc 4x4 matrix in column-major order, the source
- * @param mres 4x4 matrix in column-major order, the result
- * @return given result matrix <i>mres</i> for chaining
- */
- public static float[] transposeMatrix(final float[] msrc, final float[] mres) {
- mres[0] = msrc[0*4];
- mres[1] = msrc[1*4];
- mres[2] = msrc[2*4];
- mres[3] = msrc[3*4];
-
- final int i4_1 = 1*4;
- mres[0+i4_1] = msrc[1+0*4];
- mres[1+i4_1] = msrc[1+1*4];
- mres[2+i4_1] = msrc[1+2*4];
- mres[3+i4_1] = msrc[1+3*4];
-
- final int i4_2 = 2*4;
- mres[0+i4_2] = msrc[2+0*4];
- mres[1+i4_2] = msrc[2+1*4];
- mres[2+i4_2] = msrc[2+2*4];
- mres[3+i4_2] = msrc[2+3*4];
-
- final int i4_3 = 3*4;
- mres[0+i4_3] = msrc[3+0*4];
- mres[1+i4_3] = msrc[3+1*4];
- mres[2+i4_3] = msrc[3+2*4];
- mres[3+i4_3] = msrc[3+3*4];
-
- return mres;
- }
-
- /**
- * Returns the determinant of the given matrix
- * @param m 4x4 matrix in column-major order, the source
- * @return the matrix determinant
- */
- public static float matrixDeterminant(final float[] m) {
- float a11 = m[ 1+4*1 ];
- float a21 = m[ 2+4*1 ];
- float a31 = m[ 3+4*1 ];
- float a12 = m[ 1+4*2 ];
- float a22 = m[ 2+4*2 ];
- float a32 = m[ 3+4*2 ];
- float a13 = m[ 1+4*3 ];
- float a23 = m[ 2+4*3 ];
- float a33 = m[ 3+4*3 ];
-
- float ret = 0;
- ret += m[ 0 ] * ( + a11*(a22*a33 - a23*a32) - a12*(a21*a33 - a23*a31) + a13*(a21*a32 - a22*a31));
- a11 = m[ 1+4*0 ];
- a21 = m[ 2+4*0 ];
- a31 = m[ 3+4*0 ];
- ret -= m[ 0+4*1 ] * ( + a11*(a22*a33 - a23*a32) - a12*(a21*a33 - a23*a31) + a13*(a21*a32 - a22*a31));
- a12 = m[ 1+4*1 ];
- a22 = m[ 2+4*1 ];
- a32 = m[ 3+4*1 ];
- ret += m[ 0+4*2 ] * ( + a11*(a22*a33 - a23*a32) - a12*(a21*a33 - a23*a31) + a13*(a21*a32 - a22*a31));
- a13 = m[ 1+4*2 ];
- a23 = m[ 2+4*2 ];
- a33 = m[ 3+4*2 ];
- ret -= m[ 0+4*3 ] * ( + a11*(a22*a33 - a23*a32) - a12*(a21*a33 - a23*a31) + a13*(a21*a32 - a22*a31));
- return ret;
- }
- /**
- * Invert the given matrix.
- * <p>
- * Returns <code>null</code> if inversion is not possible,
- * e.g. matrix is singular due to a bad matrix.
- * </p>
- *
- * @param msrc 4x4 matrix in column-major order, the source
- * @param mres 4x4 matrix in column-major order, the result - may be <code>msrc</code> (in-place)
- * @return given result matrix <i>mres</i> for chaining if successful, otherwise <code>null</code>. See above.
- */
- public static float[] invertMatrix(final float[] msrc, final float[] mres) {
- final float scale;
- {
- float max = Math.abs(msrc[0]);
-
- for( int i = 1; i < 16; i++ ) {
- final float a = Math.abs(msrc[i]);
- if( a > max ) max = a;
- }
- if( 0 == max ) {
- return null;
- }
- scale = 1.0f/max;
- }
-
- final float a11 = msrc[0+4*0]*scale;
- final float a21 = msrc[1+4*0]*scale;
- final float a31 = msrc[2+4*0]*scale;
- final float a41 = msrc[3+4*0]*scale;
- final float a12 = msrc[0+4*1]*scale;
- final float a22 = msrc[1+4*1]*scale;
- final float a32 = msrc[2+4*1]*scale;
- final float a42 = msrc[3+4*1]*scale;
- final float a13 = msrc[0+4*2]*scale;
- final float a23 = msrc[1+4*2]*scale;
- final float a33 = msrc[2+4*2]*scale;
- final float a43 = msrc[3+4*2]*scale;
- final float a14 = msrc[0+4*3]*scale;
- final float a24 = msrc[1+4*3]*scale;
- final float a34 = msrc[2+4*3]*scale;
- final float a44 = msrc[3+4*3]*scale;
-
- final float m11 = + a22*(a33*a44 - a34*a43) - a23*(a32*a44 - a34*a42) + a24*(a32*a43 - a33*a42);
- final float m12 = -( + a21*(a33*a44 - a34*a43) - a23*(a31*a44 - a34*a41) + a24*(a31*a43 - a33*a41));
- final float m13 = + a21*(a32*a44 - a34*a42) - a22*(a31*a44 - a34*a41) + a24*(a31*a42 - a32*a41);
- final float m14 = -( + a21*(a32*a43 - a33*a42) - a22*(a31*a43 - a33*a41) + a23*(a31*a42 - a32*a41));
- final float m21 = -( + a12*(a33*a44 - a34*a43) - a13*(a32*a44 - a34*a42) + a14*(a32*a43 - a33*a42));
- final float m22 = + a11*(a33*a44 - a34*a43) - a13*(a31*a44 - a34*a41) + a14*(a31*a43 - a33*a41);
- final float m23 = -( + a11*(a32*a44 - a34*a42) - a12*(a31*a44 - a34*a41) + a14*(a31*a42 - a32*a41));
- final float m24 = + a11*(a32*a43 - a33*a42) - a12*(a31*a43 - a33*a41) + a13*(a31*a42 - a32*a41);
- final float m31 = + a12*(a23*a44 - a24*a43) - a13*(a22*a44 - a24*a42) + a14*(a22*a43 - a23*a42);
- final float m32 = -( + a11*(a23*a44 - a24*a43) - a13*(a21*a44 - a24*a41) + a14*(a21*a43 - a23*a41));
- final float m33 = + a11*(a22*a44 - a24*a42) - a12*(a21*a44 - a24*a41) + a14*(a21*a42 - a22*a41);
- final float m34 = -( + a11*(a22*a43 - a23*a42) - a12*(a21*a43 - a23*a41) + a13*(a21*a42 - a22*a41));
- final float m41 = -( + a12*(a23*a34 - a24*a33) - a13*(a22*a34 - a24*a32) + a14*(a22*a33 - a23*a32));
- final float m42 = + a11*(a23*a34 - a24*a33) - a13*(a21*a34 - a24*a31) + a14*(a21*a33 - a23*a31);
- final float m43 = -( + a11*(a22*a34 - a24*a32) - a12*(a21*a34 - a24*a31) + a14*(a21*a32 - a22*a31));
- final float m44 = + a11*(a22*a33 - a23*a32) - a12*(a21*a33 - a23*a31) + a13*(a21*a32 - a22*a31);
-
- final float det = (a11*m11 + a12*m12 + a13*m13 + a14*m14)/scale;
- if( 0 == det ) {
- return null;
- }
- final float invdet = 1.0f / det;
-
- mres[0+4*0] = m11 * invdet;
- mres[1+4*0] = m12 * invdet;
- mres[2+4*0] = m13 * invdet;
- mres[3+4*0] = m14 * invdet;
- mres[0+4*1] = m21 * invdet;
- mres[1+4*1] = m22 * invdet;
- mres[2+4*1] = m23 * invdet;
- mres[3+4*1] = m24 * invdet;
- mres[0+4*2] = m31 * invdet;
- mres[1+4*2] = m32 * invdet;
- mres[2+4*2] = m33 * invdet;
- mres[3+4*2] = m34 * invdet;
- mres[0+4*3] = m41 * invdet;
- mres[1+4*3] = m42 * invdet;
- mres[2+4*3] = m43 * invdet;
- mres[3+4*3] = m44 * invdet;
- return mres;
- }
-
- /**
- * Map object coordinates to window coordinates.
- * <p>
- * Traditional <code>gluProject</code> implementation.
- * </p>
- *
- * @param objx
- * @param objy
- * @param objz
- * @param modelMatrix 4x4 modelview matrix
- * @param modelMatrix_offset
- * @param projMatrix 4x4 projection matrix
- * @param projMatrix_offset
- * @param viewport 4 component viewport vector
- * @param viewport_offset
- * @param win_pos 3 component window coordinate, the result
- * @param win_pos_offset
- * @param vec4Tmp1 4 component vector for temp storage
- * @param vec4Tmp2 4 component vector for temp storage
- * @return true if successful, otherwise false (z is 1)
- */
- public static boolean mapObjToWin(final float objx, final float objy, final float objz,
- final float[] modelMatrix, final int modelMatrix_offset,
- final float[] projMatrix, final int projMatrix_offset,
- final int[] viewport, final int viewport_offset,
- final float[] win_pos, final int win_pos_offset,
- final float[/*4*/] vec4Tmp1, final float[/*4*/] vec4Tmp2) {
- vec4Tmp1[0] = objx;
- vec4Tmp1[1] = objy;
- vec4Tmp1[2] = objz;
- vec4Tmp1[3] = 1.0f;
-
- // vec4Tmp2 = Mv * o
- // vec4Tmp1 = P * vec4Tmp2
- // vec4Tmp1 = P * ( Mv * o )
- // vec4Tmp1 = P * Mv * o
- multMatrixVec(modelMatrix, modelMatrix_offset, vec4Tmp1, 0, vec4Tmp2, 0);
- multMatrixVec(projMatrix, projMatrix_offset, vec4Tmp2, 0, vec4Tmp1, 0);
-
- if (vec4Tmp1[3] == 0.0f) {
- return false;
- }
-
- vec4Tmp1[3] = (1.0f / vec4Tmp1[3]) * 0.5f;
-
- // Map x, y and z to range 0-1
- vec4Tmp1[0] = vec4Tmp1[0] * vec4Tmp1[3] + 0.5f;
- vec4Tmp1[1] = vec4Tmp1[1] * vec4Tmp1[3] + 0.5f;
- vec4Tmp1[2] = vec4Tmp1[2] * vec4Tmp1[3] + 0.5f;
-
- // Map x,y to viewport
- win_pos[0+win_pos_offset] = vec4Tmp1[0] * viewport[2+viewport_offset] + viewport[0+viewport_offset];
- win_pos[1+win_pos_offset] = vec4Tmp1[1] * viewport[3+viewport_offset] + viewport[1+viewport_offset];
- win_pos[2+win_pos_offset] = vec4Tmp1[2];
-
- return true;
- }
-
- /**
- * Map window coordinates to object coordinates.
- * <p>
- * Traditional <code>gluUnProject</code> implementation.
- * </p>
- *
- * @param winx
- * @param winy
- * @param winz
- * @param modelMatrix 4x4 modelview matrix
- * @param modelMatrix_offset
- * @param projMatrix 4x4 projection matrix
- * @param projMatrix_offset
- * @param viewport 4 component viewport vector
- * @param viewport_offset
- * @param obj_pos 3 component object coordinate, the result
- * @param obj_pos_offset
- * @param mat4Tmp1 16 component matrix for temp storage
- * @param mat4Tmp2 16 component matrix for temp storage
- * @return true if successful, otherwise false (failed to invert matrix, or becomes infinity due to zero z)
- */
- public static boolean mapWinToObj(final float winx, final float winy, final float winz,
- final float[] modelMatrix, final int modelMatrix_offset,
- final float[] projMatrix, final int projMatrix_offset,
- final int[] viewport, final int viewport_offset,
- final float[] obj_pos, final int obj_pos_offset,
- final float[/*16*/] mat4Tmp1, final float[/*16*/] mat4Tmp2) {
- // mat4Tmp1 = P x Mv
- multMatrix(projMatrix, projMatrix_offset, modelMatrix, modelMatrix_offset, mat4Tmp1, 0);
-
- // mat4Tmp1 = Inv(P x Mv)
- if ( null == invertMatrix(mat4Tmp1, mat4Tmp1) ) {
- return false;
- }
- mat4Tmp2[0] = winx;
- mat4Tmp2[1] = winy;
- mat4Tmp2[2] = winz;
- mat4Tmp2[3] = 1.0f;
-
- // Map x and y from window coordinates
- mat4Tmp2[0] = (mat4Tmp2[0] - viewport[0+viewport_offset]) / viewport[2+viewport_offset];
- mat4Tmp2[1] = (mat4Tmp2[1] - viewport[1+viewport_offset]) / viewport[3+viewport_offset];
-
- // Map to range -1 to 1
- mat4Tmp2[0] = mat4Tmp2[0] * 2 - 1;
- mat4Tmp2[1] = mat4Tmp2[1] * 2 - 1;
- mat4Tmp2[2] = mat4Tmp2[2] * 2 - 1;
-
- final int raw_off = 4;
- // object raw coords = Inv(P x Mv) * winPos -> mat4Tmp2
- multMatrixVec(mat4Tmp1, 0, mat4Tmp2, 0, mat4Tmp2, raw_off);
-
- if (mat4Tmp2[3+raw_off] == 0.0) {
- return false;
- }
-
- mat4Tmp2[3+raw_off] = 1.0f / mat4Tmp2[3+raw_off];
-
- obj_pos[0+obj_pos_offset] = mat4Tmp2[0+raw_off] * mat4Tmp2[3+raw_off];
- obj_pos[1+obj_pos_offset] = mat4Tmp2[1+raw_off] * mat4Tmp2[3+raw_off];
- obj_pos[2+obj_pos_offset] = mat4Tmp2[2+raw_off] * mat4Tmp2[3+raw_off];
-
- return true;
- }
-
- /**
- * Map window coordinates to object coordinates.
- * <p>
- * Traditional <code>gluUnProject4</code> implementation.
- * </p>
- *
- * @param winx
- * @param winy
- * @param winz
- * @param clipw
- * @param modelMatrix 4x4 modelview matrix
- * @param modelMatrix_offset
- * @param projMatrix 4x4 projection matrix
- * @param projMatrix_offset
- * @param viewport 4 component viewport vector
- * @param viewport_offset
- * @param near
- * @param far
- * @param obj_pos 4 component object coordinate, the result
- * @param obj_pos_offset
- * @param mat4Tmp1 16 component matrix for temp storage
- * @param mat4Tmp2 16 component matrix for temp storage
- * @return true if successful, otherwise false (failed to invert matrix, or becomes infinity due to zero z)
- */
- public static boolean mapWinToObj4(final float winx, final float winy, final float winz, final float clipw,
- final float[] modelMatrix, final int modelMatrix_offset,
- final float[] projMatrix, final int projMatrix_offset,
- final int[] viewport, final int viewport_offset,
- final float near, final float far,
- final float[] obj_pos, final int obj_pos_offset,
- final float[/*16*/] mat4Tmp1, final float[/*16*/] mat4Tmp2) {
- // mat4Tmp1 = P x Mv
- multMatrix(projMatrix, projMatrix_offset, modelMatrix, modelMatrix_offset, mat4Tmp1, 0);
-
- // mat4Tmp1 = Inv(P x Mv)
- if ( null == invertMatrix(mat4Tmp1, mat4Tmp1) ) {
- return false;
- }
-
- mat4Tmp2[0] = winx;
- mat4Tmp2[1] = winy;
- mat4Tmp2[2] = winz;
- mat4Tmp2[3] = clipw;
-
- // Map x and y from window coordinates
- mat4Tmp2[0] = (mat4Tmp2[0] - viewport[0+viewport_offset]) / viewport[2+viewport_offset];
- mat4Tmp2[1] = (mat4Tmp2[1] - viewport[1+viewport_offset]) / viewport[3+viewport_offset];
- mat4Tmp2[2] = (mat4Tmp2[2] - near) / (far - near);
-
- // Map to range -1 to 1
- mat4Tmp2[0] = mat4Tmp2[0] * 2 - 1;
- mat4Tmp2[1] = mat4Tmp2[1] * 2 - 1;
- mat4Tmp2[2] = mat4Tmp2[2] * 2 - 1;
-
- final int raw_off = 4;
- // object raw coords = Inv(P x Mv) * winPos -> mat4Tmp2
- multMatrixVec(mat4Tmp1, 0, mat4Tmp2, 0, mat4Tmp2, raw_off);
-
- if (mat4Tmp2[3+raw_off] == 0.0) {
- return false;
- }
-
- obj_pos[0+obj_pos_offset] = mat4Tmp2[0+raw_off];
- obj_pos[1+obj_pos_offset] = mat4Tmp2[1+raw_off];
- obj_pos[2+obj_pos_offset] = mat4Tmp2[2+raw_off];
- obj_pos[3+obj_pos_offset] = mat4Tmp2[3+raw_off];
-
- return true;
- }
-
- /**
- * Multiply matrix: [d] = [a] x [b]
- * @param a 4x4 matrix in column-major order
- * @param b 4x4 matrix in column-major order
- * @param d result a*b in column-major order
- */
- public static void multMatrix(final float[] a, final int a_off, final float[] b, final int b_off, final float[] d, final int d_off) {
- final float b00 = b[b_off+0+0*4];
- final float b10 = b[b_off+1+0*4];
- final float b20 = b[b_off+2+0*4];
- final float b30 = b[b_off+3+0*4];
- final float b01 = b[b_off+0+1*4];
- final float b11 = b[b_off+1+1*4];
- final float b21 = b[b_off+2+1*4];
- final float b31 = b[b_off+3+1*4];
- final float b02 = b[b_off+0+2*4];
- final float b12 = b[b_off+1+2*4];
- final float b22 = b[b_off+2+2*4];
- final float b32 = b[b_off+3+2*4];
- final float b03 = b[b_off+0+3*4];
- final float b13 = b[b_off+1+3*4];
- final float b23 = b[b_off+2+3*4];
- final float b33 = b[b_off+3+3*4];
-
- float ai0=a[a_off+ 0*4]; // row-0 of a
- float ai1=a[a_off+ 1*4];
- float ai2=a[a_off+ 2*4];
- float ai3=a[a_off+ 3*4];
- d[d_off+ 0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
- d[d_off+ 1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
- d[d_off+ 2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
- d[d_off+ 3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
-
- ai0=a[a_off+1+0*4]; // row-1 of a
- ai1=a[a_off+1+1*4];
- ai2=a[a_off+1+2*4];
- ai3=a[a_off+1+3*4];
- d[d_off+1+0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
- d[d_off+1+1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
- d[d_off+1+2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
- d[d_off+1+3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
-
- ai0=a[a_off+2+0*4]; // row-2 of a
- ai1=a[a_off+2+1*4];
- ai2=a[a_off+2+2*4];
- ai3=a[a_off+2+3*4];
- d[d_off+2+0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
- d[d_off+2+1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
- d[d_off+2+2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
- d[d_off+2+3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
-
- ai0=a[a_off+3+0*4]; // row-3 of a
- ai1=a[a_off+3+1*4];
- ai2=a[a_off+3+2*4];
- ai3=a[a_off+3+3*4];
- d[d_off+3+0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
- d[d_off+3+1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
- d[d_off+3+2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
- d[d_off+3+3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
- }
-
- /**
- * Multiply matrix: [d] = [a] x [b]
- * @param a 4x4 matrix in column-major order
- * @param b 4x4 matrix in column-major order
- * @param d result a*b in column-major order
- * @return given result matrix <i>d</i> for chaining
- */
- public static float[] multMatrix(final float[] a, final float[] b, final float[] d) {
- final float b00 = b[0+0*4];
- final float b10 = b[1+0*4];
- final float b20 = b[2+0*4];
- final float b30 = b[3+0*4];
- final float b01 = b[0+1*4];
- final float b11 = b[1+1*4];
- final float b21 = b[2+1*4];
- final float b31 = b[3+1*4];
- final float b02 = b[0+2*4];
- final float b12 = b[1+2*4];
- final float b22 = b[2+2*4];
- final float b32 = b[3+2*4];
- final float b03 = b[0+3*4];
- final float b13 = b[1+3*4];
- final float b23 = b[2+3*4];
- final float b33 = b[3+3*4];
-
- float ai0=a[ 0*4]; // row-0 of a
- float ai1=a[ 1*4];
- float ai2=a[ 2*4];
- float ai3=a[ 3*4];
- d[ 0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
- d[ 1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
- d[ 2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
- d[ 3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
-
- ai0=a[1+0*4]; // row-1 of a
- ai1=a[1+1*4];
- ai2=a[1+2*4];
- ai3=a[1+3*4];
- d[1+0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
- d[1+1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
- d[1+2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
- d[1+3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
-
- ai0=a[2+0*4]; // row-2 of a
- ai1=a[2+1*4];
- ai2=a[2+2*4];
- ai3=a[2+3*4];
- d[2+0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
- d[2+1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
- d[2+2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
- d[2+3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
-
- ai0=a[3+0*4]; // row-3 of a
- ai1=a[3+1*4];
- ai2=a[3+2*4];
- ai3=a[3+3*4];
- d[3+0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
- d[3+1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
- d[3+2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
- d[3+3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
-
- return d;
- }
-
- /**
- * Multiply matrix: [a] = [a] x [b]
- * @param a 4x4 matrix in column-major order (also result)
- * @param b 4x4 matrix in column-major order
- */
- public static void multMatrix(final float[] a, final int a_off, final float[] b, final int b_off) {
- final float b00 = b[b_off+0+0*4];
- final float b10 = b[b_off+1+0*4];
- final float b20 = b[b_off+2+0*4];
- final float b30 = b[b_off+3+0*4];
- final float b01 = b[b_off+0+1*4];
- final float b11 = b[b_off+1+1*4];
- final float b21 = b[b_off+2+1*4];
- final float b31 = b[b_off+3+1*4];
- final float b02 = b[b_off+0+2*4];
- final float b12 = b[b_off+1+2*4];
- final float b22 = b[b_off+2+2*4];
- final float b32 = b[b_off+3+2*4];
- final float b03 = b[b_off+0+3*4];
- final float b13 = b[b_off+1+3*4];
- final float b23 = b[b_off+2+3*4];
- final float b33 = b[b_off+3+3*4];
-
- float ai0=a[a_off+ 0*4]; // row-0 of a
- float ai1=a[a_off+ 1*4];
- float ai2=a[a_off+ 2*4];
- float ai3=a[a_off+ 3*4];
- a[a_off+ 0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
- a[a_off+ 1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
- a[a_off+ 2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
- a[a_off+ 3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
-
- ai0=a[a_off+1+0*4]; // row-1 of a
- ai1=a[a_off+1+1*4];
- ai2=a[a_off+1+2*4];
- ai3=a[a_off+1+3*4];
- a[a_off+1+0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
- a[a_off+1+1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
- a[a_off+1+2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
- a[a_off+1+3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
-
- ai0=a[a_off+2+0*4]; // row-2 of a
- ai1=a[a_off+2+1*4];
- ai2=a[a_off+2+2*4];
- ai3=a[a_off+2+3*4];
- a[a_off+2+0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
- a[a_off+2+1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
- a[a_off+2+2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
- a[a_off+2+3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
-
- ai0=a[a_off+3+0*4]; // row-3 of a
- ai1=a[a_off+3+1*4];
- ai2=a[a_off+3+2*4];
- ai3=a[a_off+3+3*4];
- a[a_off+3+0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
- a[a_off+3+1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
- a[a_off+3+2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
- a[a_off+3+3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
- }
-
- /**
- * Multiply matrix: [a] = [a] x [b]
- * @param a 4x4 matrix in column-major order (also result)
- * @param b 4x4 matrix in column-major order
- * @return given result matrix <i>a</i> for chaining
- */
- public static float[] multMatrix(final float[] a, final float[] b) {
- final float b00 = b[0+0*4];
- final float b10 = b[1+0*4];
- final float b20 = b[2+0*4];
- final float b30 = b[3+0*4];
- final float b01 = b[0+1*4];
- final float b11 = b[1+1*4];
- final float b21 = b[2+1*4];
- final float b31 = b[3+1*4];
- final float b02 = b[0+2*4];
- final float b12 = b[1+2*4];
- final float b22 = b[2+2*4];
- final float b32 = b[3+2*4];
- final float b03 = b[0+3*4];
- final float b13 = b[1+3*4];
- final float b23 = b[2+3*4];
- final float b33 = b[3+3*4];
-
- float ai0=a[ 0*4]; // row-0 of a
- float ai1=a[ 1*4];
- float ai2=a[ 2*4];
- float ai3=a[ 3*4];
- a[ 0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
- a[ 1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
- a[ 2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
- a[ 3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
-
- ai0=a[1+0*4]; // row-1 of a
- ai1=a[1+1*4];
- ai2=a[1+2*4];
- ai3=a[1+3*4];
- a[1+0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
- a[1+1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
- a[1+2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
- a[1+3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
-
- ai0=a[2+0*4]; // row-2 of a
- ai1=a[2+1*4];
- ai2=a[2+2*4];
- ai3=a[2+3*4];
- a[2+0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
- a[2+1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
- a[2+2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
- a[2+3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
-
- ai0=a[3+0*4]; // row-3 of a
- ai1=a[3+1*4];
- ai2=a[3+2*4];
- ai3=a[3+3*4];
- a[3+0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
- a[3+1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
- a[3+2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
- a[3+3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
-
- return a;
- }
-
- /**
- * Multiply matrix: [d] = [a] x [b]
- * @param a 4x4 matrix in column-major order
- * @param b 4x4 matrix in column-major order
- * @param d result a*b in column-major order
- */
- public static void multMatrix(final FloatBuffer a, final FloatBuffer b, final float[] d) {
- final int a_off = a.position();
- final int b_off = b.position();
- for (int i = 0; i < 4; i++) {
- // one row in column-major order
- final int a_off_i = a_off+i;
- final float ai0=a.get(a_off_i+0*4), ai1=a.get(a_off_i+1*4), ai2=a.get(a_off_i+2*4), ai3=a.get(a_off_i+3*4); // row-i of a
- d[i+0*4] = ai0 * b.get(b_off+0+0*4) + ai1 * b.get(b_off+1+0*4) + ai2 * b.get(b_off+2+0*4) + ai3 * b.get(b_off+3+0*4) ;
- d[i+1*4] = ai0 * b.get(b_off+0+1*4) + ai1 * b.get(b_off+1+1*4) + ai2 * b.get(b_off+2+1*4) + ai3 * b.get(b_off+3+1*4) ;
- d[i+2*4] = ai0 * b.get(b_off+0+2*4) + ai1 * b.get(b_off+1+2*4) + ai2 * b.get(b_off+2+2*4) + ai3 * b.get(b_off+3+2*4) ;
- d[i+3*4] = ai0 * b.get(b_off+0+3*4) + ai1 * b.get(b_off+1+3*4) + ai2 * b.get(b_off+2+3*4) + ai3 * b.get(b_off+3+3*4) ;
- }
- }
-
- /**
- * Multiply matrix: [a] = [a] x [b]
- * @param a 4x4 matrix in column-major order (also result)
- * @param b 4x4 matrix in column-major order
- */
- public static void multMatrix(final FloatBuffer a, final FloatBuffer b) {
- final int a_off = a.position();
- final int b_off = b.position();
- for (int i = 0; i < 4; i++) {
- // one row in column-major order
- final int a_off_i = a_off+i;
- final float ai0=a.get(a_off_i+0*4), ai1=a.get(a_off_i+1*4), ai2=a.get(a_off_i+2*4), ai3=a.get(a_off_i+3*4); // row-i of a
- a.put(a_off_i+0*4 , ai0 * b.get(b_off+0+0*4) + ai1 * b.get(b_off+1+0*4) + ai2 * b.get(b_off+2+0*4) + ai3 * b.get(b_off+3+0*4) );
- a.put(a_off_i+1*4 , ai0 * b.get(b_off+0+1*4) + ai1 * b.get(b_off+1+1*4) + ai2 * b.get(b_off+2+1*4) + ai3 * b.get(b_off+3+1*4) );
- a.put(a_off_i+2*4 , ai0 * b.get(b_off+0+2*4) + ai1 * b.get(b_off+1+2*4) + ai2 * b.get(b_off+2+2*4) + ai3 * b.get(b_off+3+2*4) );
- a.put(a_off_i+3*4 , ai0 * b.get(b_off+0+3*4) + ai1 * b.get(b_off+1+3*4) + ai2 * b.get(b_off+2+3*4) + ai3 * b.get(b_off+3+3*4) );
- }
- }
-
- /**
- * @param m_in 4x4 matrix in column-major order
- * @param m_in_off
- * @param v_in 4-component column-vector
- * @param v_out m_in * v_in
- */
- public static void multMatrixVec(final float[] m_in, final int m_in_off,
- final float[] v_in, final int v_in_off,
- final float[] v_out, final int v_out_off) {
- // (one matrix row in column-major order) X (column vector)
- v_out[0 + v_out_off] = v_in[0+v_in_off] * m_in[0*4+m_in_off ] + v_in[1+v_in_off] * m_in[1*4+m_in_off ] +
- v_in[2+v_in_off] * m_in[2*4+m_in_off ] + v_in[3+v_in_off] * m_in[3*4+m_in_off ];
-
- final int m_in_off_1 = 1+m_in_off;
- v_out[1 + v_out_off] = v_in[0+v_in_off] * m_in[0*4+m_in_off_1] + v_in[1+v_in_off] * m_in[1*4+m_in_off_1] +
- v_in[2+v_in_off] * m_in[2*4+m_in_off_1] + v_in[3+v_in_off] * m_in[3*4+m_in_off_1];
-
- final int m_in_off_2 = 2+m_in_off;
- v_out[2 + v_out_off] = v_in[0+v_in_off] * m_in[0*4+m_in_off_2] + v_in[1+v_in_off] * m_in[1*4+m_in_off_2] +
- v_in[2+v_in_off] * m_in[2*4+m_in_off_2] + v_in[3+v_in_off] * m_in[3*4+m_in_off_2];
-
- final int m_in_off_3 = 3+m_in_off;
- v_out[3 + v_out_off] = v_in[0+v_in_off] * m_in[0*4+m_in_off_3] + v_in[1+v_in_off] * m_in[1*4+m_in_off_3] +
- v_in[2+v_in_off] * m_in[2*4+m_in_off_3] + v_in[3+v_in_off] * m_in[3*4+m_in_off_3];
- }
-
- /**
- * @param m_in 4x4 matrix in column-major order
- * @param m_in_off
- * @param v_in 4-component column-vector
- * @param v_out m_in * v_in
- */
- public static void multMatrixVec(final float[] m_in, final int m_in_off,
- final float[] v_in, final float[] v_out) {
- // (one matrix row in column-major order) X (column vector)
- v_out[0] = v_in[0] * m_in[0*4+m_in_off ] + v_in[1] * m_in[1*4+m_in_off ] +
- v_in[2] * m_in[2*4+m_in_off ] + v_in[3] * m_in[3*4+m_in_off ];
-
- final int m_in_off_1 = 1+m_in_off;
- v_out[1] = v_in[0] * m_in[0*4+m_in_off_1] + v_in[1] * m_in[1*4+m_in_off_1] +
- v_in[2] * m_in[2*4+m_in_off_1] + v_in[3] * m_in[3*4+m_in_off_1];
-
- final int m_in_off_2 = 2+m_in_off;
- v_out[2] = v_in[0] * m_in[0*4+m_in_off_2] + v_in[1] * m_in[1*4+m_in_off_2] +
- v_in[2] * m_in[2*4+m_in_off_2] + v_in[3] * m_in[3*4+m_in_off_2];
-
- final int m_in_off_3 = 3+m_in_off;
- v_out[3] = v_in[0] * m_in[0*4+m_in_off_3] + v_in[1] * m_in[1*4+m_in_off_3] +
- v_in[2] * m_in[2*4+m_in_off_3] + v_in[3] * m_in[3*4+m_in_off_3];
- }
-
- /**
- * @param m_in 4x4 matrix in column-major order
- * @param m_in_off
- * @param v_in 4-component column-vector
- * @param v_out m_in * v_in
- * @return given result vector <i>v_out</i> for chaining
- */
- public static float[] multMatrixVec(final float[] m_in, final float[] v_in, final float[] v_out) {
- // (one matrix row in column-major order) X (column vector)
- v_out[0] = v_in[0] * m_in[0*4 ] + v_in[1] * m_in[1*4 ] +
- v_in[2] * m_in[2*4 ] + v_in[3] * m_in[3*4 ];
-
- v_out[1] = v_in[0] * m_in[0*4+1] + v_in[1] * m_in[1*4+1] +
- v_in[2] * m_in[2*4+1] + v_in[3] * m_in[3*4+1];
-
- v_out[2] = v_in[0] * m_in[0*4+2] + v_in[1] * m_in[1*4+2] +
- v_in[2] * m_in[2*4+2] + v_in[3] * m_in[3*4+2];
-
- v_out[3] = v_in[0] * m_in[0*4+3] + v_in[1] * m_in[1*4+3] +
- v_in[2] * m_in[2*4+3] + v_in[3] * m_in[3*4+3];
-
- return v_out;
- }
-
- /**
- * @param m_in 4x4 matrix in column-major order
- * @param v_in 4-component column-vector
- * @param v_out m_in * v_in
- */
- public static void multMatrixVec(final FloatBuffer m_in, final float[] v_in, final float[] v_out) {
- final int m_in_off = m_in.position();
- for (int i = 0; i < 4; i++) {
- // (one matrix row in column-major order) X (column vector)
- final int i_m_in_off = i+m_in_off;
- v_out[i] =
- v_in[0] * m_in.get(0*4+i_m_in_off) +
- v_in[1] * m_in.get(1*4+i_m_in_off) +
- v_in[2] * m_in.get(2*4+i_m_in_off) +
- v_in[3] * m_in.get(3*4+i_m_in_off);
- }
- }
-
- /**
- * Affine 3f-vector transformation by 4x4 matrix
- *
- * 4x4 matrix multiplication with 3-component vector,
- * using {@code 1} for for {@code v_in[3]} and dropping {@code v_out[3]},
- * which shall be {@code 1}.
- *
- * @param m_in 4x4 matrix in column-major order
- * @param m_in_off
- * @param v_in 3-component column-vector
- * @param v_out m_in * v_in, 3-component column-vector
- * @return given result vector <i>v_out</i> for chaining
- */
- public static float[] multMatrixVec3(final float[] m_in, final float[] v_in, final float[] v_out) {
- // (one matrix row in column-major order) X (column vector)
- v_out[0] = v_in[0] * m_in[0*4 ] + v_in[1] * m_in[1*4 ] +
- v_in[2] * m_in[2*4 ] + 1f * m_in[3*4 ];
-
- v_out[1] = v_in[0] * m_in[0*4+1] + v_in[1] * m_in[1*4+1] +
- v_in[2] * m_in[2*4+1] + 1f * m_in[3*4+1];
-
- v_out[2] = v_in[0] * m_in[0*4+2] + v_in[1] * m_in[1*4+2] +
- v_in[2] * m_in[2*4+2] + 1f * m_in[3*4+2];
-
- return v_out;
- }
-
- /**
- * @param sb optional passed StringBuilder instance to be used
- * @param f the format string of one floating point, i.e. "%10.5f", see {@link java.util.Formatter}
- * @param a mxn matrix (rows x columns)
- * @param aOffset offset to <code>a</code>'s current position
- * @param rows
- * @param columns
- * @param rowMajorOrder if true floats are layed out in row-major-order, otherwise column-major-order (OpenGL)
- * @param row row number to print
- * @return matrix row string representation
- */
- public static StringBuilder matrixRowToString(StringBuilder sb, final String f,
- final FloatBuffer a, final int aOffset,
- final int rows, final int columns, final boolean rowMajorOrder, final int row) {
- if(null == sb) {
- sb = new StringBuilder();
- }
- final int a0 = aOffset + a.position();
- if(rowMajorOrder) {
- for(int c=0; c<columns; c++) {
- sb.append( String.format((Locale)null, f+", ", a.get( a0 + row*columns + c ) ) );
- }
- } else {
- for(int r=0; r<columns; r++) {
- sb.append( String.format((Locale)null, f+", ", a.get( a0 + row + r*rows ) ) );
- }
- }
- return sb;
- }
-
- /**
- * @param sb optional passed StringBuilder instance to be used
- * @param f the format string of one floating point, i.e. "%10.5f", see {@link java.util.Formatter}
- * @param a mxn matrix (rows x columns)
- * @param aOffset offset to <code>a</code>'s current position
- * @param rows
- * @param columns
- * @param rowMajorOrder if true floats are layed out in row-major-order, otherwise column-major-order (OpenGL)
- * @param row row number to print
- * @return matrix row string representation
- */
- public static StringBuilder matrixRowToString(StringBuilder sb, final String f,
- final float[] a, final int aOffset, final int rows, final int columns, final boolean rowMajorOrder, final int row) {
- if(null == sb) {
- sb = new StringBuilder();
- }
- if(rowMajorOrder) {
- for(int c=0; c<columns; c++) {
- sb.append( String.format((Locale)null, f+", ", a[ aOffset + row*columns + c ] ) );
- }
- } else {
- for(int r=0; r<columns; r++) {
- sb.append( String.format((Locale)null, f+", ", a[ aOffset + row + r*rows ] ) );
- }
- }
- return sb;
- }
-
- /**
- * @param sb optional passed StringBuilder instance to be used
- * @param rowPrefix optional prefix for each row
- * @param f the format string of one floating point, i.e. "%10.5f", see {@link java.util.Formatter}
- * @param a mxn matrix (rows x columns)
- * @param aOffset offset to <code>a</code>'s current position
- * @param rows
- * @param columns
- * @param rowMajorOrder if true floats are layed out in row-major-order, otherwise column-major-order (OpenGL)
- * @return matrix string representation
- */
- public static StringBuilder matrixToString(StringBuilder sb, final String rowPrefix, final String f,
- final FloatBuffer a, final int aOffset, final int rows, final int columns, final boolean rowMajorOrder) {
- if(null == sb) {
- sb = new StringBuilder();
- }
- final String prefix = ( null == rowPrefix ) ? "" : rowPrefix;
- sb.append(prefix).append("{ ");
- for(int i=0; i<rows; i++) {
- if( 0 < i ) {
- sb.append(prefix).append(" ");
- }
- matrixRowToString(sb, f, a, aOffset, rows, columns, rowMajorOrder, i);
- sb.append(System.lineSeparator());
- }
- sb.append(prefix).append("}").append(System.lineSeparator());
- return sb;
- }
-
- /**
- * @param sb optional passed StringBuilder instance to be used
- * @param rowPrefix optional prefix for each row
- * @param f the format string of one floating point, i.e. "%10.5f", see {@link java.util.Formatter}
- * @param a mxn matrix (rows x columns)
- * @param aOffset offset to <code>a</code>'s current position
- * @param rows
- * @param columns
- * @param rowMajorOrder if true floats are layed out in row-major-order, otherwise column-major-order (OpenGL)
- * @return matrix string representation
- */
- public static StringBuilder matrixToString(StringBuilder sb, final String rowPrefix, final String f,
- final float[] a, final int aOffset, final int rows, final int columns, final boolean rowMajorOrder) {
- if(null == sb) {
- sb = new StringBuilder();
- }
- final String prefix = ( null == rowPrefix ) ? "" : rowPrefix;
- sb.append(prefix).append("{ ");
- for(int i=0; i<rows; i++) {
- if( 0 < i ) {
- sb.append(prefix).append(" ");
- }
- matrixRowToString(sb, f, a, aOffset, rows, columns, rowMajorOrder, i);
- sb.append(System.lineSeparator());
- }
- sb.append(prefix).append("}").append(System.lineSeparator());
- return sb;
- }
-
- //
- // Scalar Ops
- //
-
- @SuppressWarnings("unused")
- private static void calculateMachineEpsilonFloat() {
- final long t0;
- if( DEBUG_EPSILON ) {
- t0 = Platform.currentTimeMillis();
- }
- float machEps = 1.0f;
- int i=0;
- do {
- machEps /= 2.0f;
- i++;
- } while (1.0f + (machEps / 2.0f) != 1.0f);
- machEpsilon = machEps;
- if( DEBUG_EPSILON ) {
- final long t1 = Platform.currentTimeMillis();
- System.err.println("MachineEpsilon: "+machEpsilon+", in "+i+" iterations within "+(t1-t0)+" ms");
- }
- }
- private static volatile boolean machEpsilonAvail = false;
- private static float machEpsilon = 0f;
- private static final boolean DEBUG_EPSILON = false;
-
- /**
- * Return computed machine Epsilon value.
- * <p>
- * The machine Epsilon value is computed once.
- * </p>
- * <p>
- * On a reference machine the result was {@link #EPSILON} in 23 iterations.
- * </p>
- * @see #EPSILON
- */
- public static float getMachineEpsilon() {
- if( !machEpsilonAvail ) {
- synchronized(FloatUtil.class) {
- if( !machEpsilonAvail ) {
- machEpsilonAvail = true;
- calculateMachineEpsilonFloat();
- }
- }
- }
- return machEpsilon;
- }
-
- public static final float E = 2.7182818284590452354f;
-
- /** The value PI, i.e. 180 degrees in radians. */
- public static final float PI = 3.14159265358979323846f;
-
- /** The value 2PI, i.e. 360 degrees in radians. */
- public static final float TWO_PI = 2f * PI;
-
- /** The value PI/2, i.e. 90 degrees in radians. */
- public static final float HALF_PI = PI / 2f;
-
- /** The value PI/4, i.e. 45 degrees in radians. */
- public static final float QUARTER_PI = PI / 4f;
-
- /** The value PI^2. */
- public final static float SQUARED_PI = PI * PI;
-
- /** Converts arc-degree to radians */
- public static float adegToRad(final float arc_degree) {
- return arc_degree * PI / 180.0f;
- }
-
- /** Converts radians to arc-degree */
- public static float radToADeg(final float rad) {
- return rad * 180.0f / PI;
- }
-
- /**
- * Epsilon for floating point {@value}, as once computed via {@link #getMachineEpsilon()} on an AMD-64 CPU.
- * <p>
- * Definition of machine epsilon guarantees that:
- * <pre>
- * 1.0f + EPSILON != 1.0f
- * </pre>
- * In other words: <i>machEps</i> is the maximum relative error of the chosen rounding procedure.
- * </p>
- * <p>
- * A number can be considered zero if it is in the range (or in the set):
- * <pre>
- * <b>MaybeZeroSet</b> e ]-<i>machEps</i> .. <i>machEps</i>[ <i>(exclusive)</i>
- * </pre>
- * While comparing floating point values, <i>machEps</i> allows to clip the relative error:
- * <pre>
- * boolean isZero = afloat < EPSILON;
- * boolean isNotZero = afloat >= EPSILON;
- *
- * boolean isEqual = abs(bfloat - afloat) < EPSILON;
- * boolean isNotEqual = abs(bfloat - afloat) >= EPSILON;
- * </pre>
- * </p>
- * @see #isEqual(float, float, float)
- * @see #isZero(float, float)
- */
- public static final float EPSILON = 1.1920929E-7f; // Float.MIN_VALUE == 1.4e-45f ; double EPSILON 2.220446049250313E-16d
-
- /**
- * Inversion Epsilon, used with equals method to determine if two inverted matrices are close enough to be considered equal.
- * <p>
- * Using {@value}, which is ~100 times {@link FloatUtil#EPSILON}.
- * </p>
- */
- public static final float INV_DEVIANCE = 1.0E-5f; // FloatUtil.EPSILON == 1.1920929E-7f; double ALLOWED_DEVIANCE: 1.0E-8f
-
- /**
- * Return true if both values are equal w/o regarding an epsilon.
- * <p>
- * Implementation considers following corner cases:
- * <ul>
- * <li>NaN == NaN</li>
- * <li>+Inf == +Inf</li>
- * <li>-Inf == -Inf</li>
- * </ul>
- * </p>
- * @see #isEqual(float, float, float)
- */
- public static boolean isEqualRaw(final float a, final float b) {
- // Values are equal (Inf, Nan .. )
- return Float.floatToIntBits(a) == Float.floatToIntBits(b);
- }
-
- /**
- * Return true if both values are equal, i.e. their absolute delta < <code>epsilon</code>.
- * <p>
- * Implementation considers following corner cases:
- * <ul>
- * <li>NaN == NaN</li>
- * <li>+Inf == +Inf</li>
- * <li>-Inf == -Inf</li>
- * </ul>
- * </p>
- * @see #EPSILON
- */
- public static boolean isEqual(final float a, final float b, final float epsilon) {
- if ( Math.abs(a - b) < epsilon ) {
- return true;
- } else {
- // Values are equal (Inf, Nan .. )
- return Float.floatToIntBits(a) == Float.floatToIntBits(b);
- }
- }
-
- /**
- * Return true if both values are equal, i.e. their absolute delta < {@link #EPSILON}.
- * <p>
- * Implementation considers following corner cases:
- * <ul>
- * <li>NaN == NaN</li>
- * <li>+Inf == +Inf</li>
- * <li>-Inf == -Inf</li>
- * </ul>
- * </p>
- * @see #EPSILON
- */
- public static boolean isEqual(final float a, final float b) {
- if ( Math.abs(a - b) < EPSILON ) {
- return true;
- } else {
- // Values are equal (Inf, Nan .. )
- return Float.floatToIntBits(a) == Float.floatToIntBits(b);
- }
- }
-
- /**
- * Return true if both values are equal, i.e. their absolute delta < {@link #EPSILON}.
- * <p>
- * Implementation does not consider corner cases like {@link #isEqual(float, float, float)}.
- * </p>
- * @see #EPSILON
- */
- public static boolean isEqual2(final float a, final float b) {
- return Math.abs(a - b) < EPSILON;
- }
-
- /**
- * Return true if both values are equal w/o regarding an epsilon.
- * <p>
- * Implementation considers following corner cases:
- * <ul>
- * <li>NaN == NaN</li>
- * <li>+Inf == +Inf</li>
- * <li>-Inf == -Inf</li>
- * <li>NaN > 0</li>
- * <li>+Inf > -Inf</li>
- * </ul>
- * </p>
- * @see #compare(float, float, float)
- */
- public static int compare(final float a, final float b) {
- if (a < b) {
- return -1; // Neither is NaN, a is smaller
- }
- if (a > b) {
- return 1; // Neither is NaN, a is larger
- }
- final int aBits = Float.floatToIntBits(a);
- final int bBits = Float.floatToIntBits(b);
- if( aBits == bBits ) {
- return 0; // Values are equal (Inf, Nan .. )
- } else if( aBits < bBits ) {
- return -1; // (-0.0, 0.0) or (!NaN, NaN)
- } else {
- return 1; // ( 0.0, -0.0) or ( NaN, !NaN)
- }
- }
-
- /**
- * Return true if both values are equal, i.e. their absolute delta < <code>epsilon</code>.
- * <p>
- * Implementation considers following corner cases:
- * <ul>
- * <li>NaN == NaN</li>
- * <li>+Inf == +Inf</li>
- * <li>-Inf == -Inf</li>
- * <li>NaN > 0</li>
- * <li>+Inf > -Inf</li>
- * </ul>
- * </p>
- * @see #EPSILON
- */
- public static int compare(final float a, final float b, final float epsilon) {
- if ( Math.abs(a - b) < epsilon ) {
- return 0;
- } else {
- return compare(a, b);
- }
- }
-
- /**
- * Return true if value is zero, i.e. it's absolute value < <code>epsilon</code>.
- * @see #EPSILON
- */
- public static boolean isZero(final float a, final float epsilon) {
- return Math.abs(a) < epsilon;
- }
-
- /**
- * Return true if value is zero, i.e. it's absolute value < {@link #EPSILON}.
- * @see #EPSILON
- */
- public static boolean isZero(final float a) {
- return Math.abs(a) < FloatUtil.EPSILON;
- }
-
- /**
- * Invokes {@link Math#abs(float)}
- * @param a float to process
- * @return absolute value of {@code a}
- * @deprecated use {@link Math#abs(float)} directly
- */
- @Deprecated
- public static float abs(final float a) { return java.lang.Math.abs(a); }
-
- public static float pow(final float a, final float b) { return (float) java.lang.Math.pow(a, b); }
-
- public static float sin(final float a) { return (float) java.lang.Math.sin(a); }
-
- public static float asin(final float a) { return (float) java.lang.Math.asin(a); }
-
- public static float cos(final float a) { return (float) java.lang.Math.cos(a); }
-
- public static float acos(final float a) { return (float) java.lang.Math.acos(a); }
-
- public static float tan(final float a) { return (float) java.lang.Math.tan(a); }
-
- public static float atan(final float a) { return (float) java.lang.Math.atan(a); }
-
- public static float atan2(final float y, final float x) { return (float) java.lang.Math.atan2(y, x); }
-
- public static float sqrt(final float a) { return (float) java.lang.Math.sqrt(a); }
-
- /**
- * Returns resolution of Z buffer of given parameter,
- * see <a href="http://www.sjbaker.org/steve/omniv/love_your_z_buffer.html">Love Your Z-Buffer</a>.
- * <pre>
- * return z * z / ( zNear * (1&lt;&lt;zBits) - z )
- * </pre>
- * Examples:
- * <pre>
- * 1.5256461E-4 = 16 zBits, -0.2 zDist, 0.1 zNear
- * 6.1033297E-6 = 16 zBits, -1.0 zDist, 0.1 zNear
- * </pre>
- * @param zBits number of bits of Z precision, i.e. z-buffer depth
- * @param z distance from the eye to the object
- * @param zNear distance from eye to near clip plane
- * @return smallest resolvable Z separation at this range.
- */
- public static float getZBufferEpsilon(final int zBits, final float z, final float zNear) {
- return z * z / ( zNear * ( 1 << zBits ) - z );
- }
-
- /**
- * Returns Z buffer value of given parameter,
- * see <a href="http://www.sjbaker.org/steve/omniv/love_your_z_buffer.html">Love Your Z-Buffer</a>.
- * <pre>
- * float a = zFar / ( zFar - zNear )
- * float b = zFar * zNear / ( zNear - zFar )
- * return (int) ( (1&lt;&lt;zBits) * ( a + b / z ) )
- * </pre>
- * @param zBits number of bits of Z precision, i.e. z-buffer depth
- * @param z distance from the eye to the object
- * @param zNear distance from eye to near clip plane
- * @param zFar distance from eye to far clip plane
- * @return z buffer value
- */
- public static int getZBufferValue(final int zBits, final float z, final float zNear, final float zFar) {
- final float a = zFar / ( zFar - zNear );
- final float b = zFar * zNear / ( zNear - zFar );
- return (int) ( (1<<zBits) * ( a + b / z ) );
- }
-
- /**
- * Returns orthogonal distance
- * (1f/zNear-1f/orthoZ) / (1f/zNear-1f/zFar);
- */
- public static float getOrthoWinZ(final float orthoZ, final float zNear, final float zFar) {
- return (1f/zNear-1f/orthoZ) / (1f/zNear-1f/zFar);
- }
-
-} \ No newline at end of file