summaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-06-27 18:16:43 +0200
committerSven Gothel <[email protected]>2014-06-27 18:16:43 +0200
commit0bded476868c5fdfe44502bfd55957469d0d72bb (patch)
tree8f3baefe8c7267a11dffacc4ba1814478c4b2123 /src/jogl/classes/com/jogamp
parent21b84da775fae5806481ecc658a207bf603126d5 (diff)
Enhance FloatUtil: Merge ProjectFloat features while adding optimized variations; PMVMatrix: Remove NIO buffer path, use backing-array only and FloatUtil direct.
- FloatUtil pptimized variants: - mapObjToWinCoords (gluProject) passing 'P x Mv' for batch operations - mapWinToObjCoords (gluUnProject) passing 'Inv(P x Mv)' for batch operations - mapWinToObjCoords (gluUnProject) passing 'Inv(P x Mv)' and two winz values for two ray picking resulting in two obj positions. (-> mapWinToRay) - PMVMatrix - dropped low performance NIO mode - simply use common backing-array and fixed offsets directly - drop ProjectFloat usage in favor of FloatUtil - reduce number of temporary arrays
Diffstat (limited to 'src/jogl/classes/com/jogamp')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java1582
-rw-r--r--src/jogl/classes/com/jogamp/opengl/math/Quaternion.java6
-rw-r--r--src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java58
-rw-r--r--src/jogl/classes/com/jogamp/opengl/math/geom/AABBox.java75
-rw-r--r--src/jogl/classes/com/jogamp/opengl/math/geom/Frustum.java2
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java449
6 files changed, 1691 insertions, 481 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java b/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java
index cf56ff0a4..f7a12f2dd 100644
--- a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java
@@ -34,6 +34,7 @@ import javax.media.opengl.GLException;
import jogamp.opengl.Debug;
import com.jogamp.common.os.Platform;
+import com.jogamp.opengl.math.geom.AABBox;
/**
* Basic Float math utility functions.
@@ -61,64 +62,263 @@ import com.jogamp.common.os.Platform;
*
* @author Erik Duijs, Kenneth Russell, et al.
*/
-public class FloatUtil {
+public final class FloatUtil {
public static final boolean DEBUG = Debug.debug("Math");
- private static final float[] IDENTITY_MATRIX =
- new float[] {
- 1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f };
+ //
+ // Matrix Ops
+ //
- private static final float[] ZERO_MATRIX =
- new float[] {
- 0.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 0.0f };
+ /**
+ * Make matrix an identity matrix
+ * @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
+ * @return given matrix for chaining
+ */
+ public static float[] makeIdentity(final float[] m, final int m_offset) {
+ 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;
+ return m;
+ }
/**
* Make matrix an identity matrix
+ * @param m 4x4 matrix in column-major order (also result)
+ * @return given matrix for chaining
*/
- public static final void makeIdentityf(float[] m, int offset) {
- for (int i = 0; i < 16; i++) {
- m[i+offset] = IDENTITY_MATRIX[i];
- }
+ 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 matrix an identity matrix
+ * @param m 4x4 matrix in column-major order (also result)
+ * @return given matrix for chaining
*/
- public static final void makeIdentityf(FloatBuffer m) {
- final int oldPos = m.position();
- m.put(IDENTITY_MATRIX);
- m.position(oldPos);
+ public static FloatBuffer makeIdentity(final FloatBuffer m) {
+ final int m_offset = m.position();
+ m.put(m_offset+0+4*0, 1f);
+ m.put(m_offset+1+4*0, 0f);
+ m.put(m_offset+2+4*0, 0f);
+ m.put(m_offset+3+4*0, 0f);
+
+ m.put(m_offset+0+4*1, 0f);
+ m.put(m_offset+1+4*1, 1f);
+ m.put(m_offset+2+4*1, 0f);
+ m.put(m_offset+3+4*1, 0f);
+
+ m.put(m_offset+0+4*2, 0f);
+ m.put(m_offset+1+4*2, 0f);
+ m.put(m_offset+2+4*2, 1f);
+ m.put(m_offset+3+4*2, 0f);
+
+ m.put(m_offset+0+4*3, 0f);
+ m.put(m_offset+1+4*3, 0f);
+ m.put(m_offset+2+4*3, 0f);
+ m.put(m_offset+3+4*3, 1f);
+ return m;
}
/**
- * Make matrix an zero matrix
+ * 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 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 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 final void makeZero(float[] m, int offset) {
- for (int i = 0; i < 16; i++) {
- m[i+offset] = 0;
- }
+ public static float[] makeTranslation(final float[] m, final int m_offset, final boolean initM, final float tx, final float ty, final float tz) {
+ if( initM ) {
+ makeIdentity(m, m_offset);
+ } else {
+ m[m_offset+0+4*0] = 1;
+ m[m_offset+1+4*1] = 1;
+ m[m_offset+2+4*2] = 1;
+ m[m_offset+3+4*3] = 1;
+ }
+ m[m_offset+0+4*3] = tx;
+ m[m_offset+1+4*3] = ty;
+ m[m_offset+2+4*3] = tz;
+ return m;
}
/**
- * Make matrix an zero matrix
+ * 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 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 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 int m_offset, final boolean initM, final float sx, final float sy, final float sz) {
+ if( initM ) {
+ makeIdentity(m, m_offset);
+ } else {
+ m[m_offset+0+4*3] = 0;
+ m[m_offset+1+4*3] = 0;
+ m[m_offset+2+4*3] = 0;
+ m[m_offset+3+4*3] = 1;
+ }
+ m[m_offset+0+4*0] = sx;
+ m[m_offset+1+4*1] = sy;
+ m[m_offset+2+4*2] = sz;
+ 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 final void makeZero(FloatBuffer m) {
- final int oldPos = m.position();
- m.put(ZERO_MATRIX);
- m.position(oldPos);
+ 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 a rotation matrix from the given axis and angle in radians.
+ * <pre>
+ Rotation matrix (Column Order):
+ xx(1-c)+c xy(1-c)+zs xz(1-c)-ys 0
+ xy(1-c)-zs yy(1-c)+c yz(1-c)+xs 0
+ xz(1-c)+ys yz(1-c)-xs zz(1-c)+c 0
+ 0 0 0 1
+ * </pre>
+ * <p>
+ * All matrix fields are set.
+ * </p>
* @see <a href="http://web.archive.org/web/20041029003853/http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q38">Matrix-FAQ Q38</a>
+ * @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
+ * @return given matrix for chaining
*/
- public static final void makeRotationAxis(final float angrad, float x, float y, float z, final float[] mat, final int mat_offset, final float[] tmpVec3f) {
+ public static float[] makeRotationAxis(final float[] m, final int m_offset, final float angrad, float x, float y, float z, final float[] tmpVec3f) {
final float c = cos(angrad);
final float ic= 1.0f - c;
final float s = sin(angrad);
@@ -127,28 +327,33 @@ public class FloatUtil {
VectorUtil.normalizeVec3(tmpVec3f);
x = tmpVec3f[0]; y = tmpVec3f[1]; z = tmpVec3f[2];
- // Rotation matrix (Row Order):
- // xx(1-c)+c xy(1-c)+zs xz(1-c)-ys 0
- // xy(1-c)-zs yy(1-c)+c yz(1-c)+xs 0
- // xz(1-c)+ys yz(1-c)-xs zz(1-c)+c 0
- // 0 0 0 1
final float xy = x*y;
final float xz = x*z;
final float xs = x*s;
final float ys = y*s;
final float yz = y*z;
final float zs = z*s;
- mat[0+0*4+mat_offset] = x*x*ic+c;
- mat[1+0*4+mat_offset] = xy*ic+zs;
- mat[2+0*4+mat_offset] = xz*ic-ys;
-
- mat[0+1*4+mat_offset] = xy*ic-zs;
- mat[1+1*4+mat_offset] = y*y*ic+c;
- mat[2+1*4+mat_offset] = yz*ic+xs;
-
- mat[0+2*4+mat_offset] = xz*ic+ys;
- mat[1+2*4+mat_offset] = yz*ic-xs;
- mat[2+2*4+mat_offset] = z*z*ic+c;
+ m[0+0*4+m_offset] = x*x*ic+c;
+ m[1+0*4+m_offset] = xy*ic+zs;
+ m[2+0*4+m_offset] = xz*ic-ys;
+ m[3+0*4+m_offset] = 0;
+
+ m[0+1*4+m_offset] = xy*ic-zs;
+ m[1+1*4+m_offset] = y*y*ic+c;
+ m[2+1*4+m_offset] = yz*ic+xs;
+ m[3+1*4+m_offset] = 0;
+
+ m[0+2*4+m_offset] = xz*ic+ys;
+ m[1+2*4+m_offset] = yz*ic-xs;
+ m[2+2*4+m_offset] = z*z*ic+c;
+ m[3+2*4+m_offset] = 0;
+
+ m[0+3*4+m_offset] = 0f;
+ m[1+3*4+m_offset] = 0f;
+ m[2+3*4+m_offset] = 0f;
+ m[3+3*4+m_offset] = 1f;
+
+ return m;
}
/**
@@ -161,9 +366,15 @@ public class FloatUtil {
* <li>x - bank</li>
* </ul>
* </p>
+ * <p>
+ * All matrix fields are set.
+ * </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 bankX the Euler pitch angle in radians. (rotation about the X axis)
* @param headingY the Euler yaw angle in radians. (rotation about the Y axis)
* @param attitudeZ the Euler roll angle in radians. (rotation about the Z axis)
+ * @return given matrix for chaining
* <p>
* Implementation does not use Quaternion and hence is exposed to
* <a href="http://web.archive.org/web/20041029003853/http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q34">Gimbal-Lock</a>
@@ -171,7 +382,7 @@ public class FloatUtil {
* @see <a href="http://web.archive.org/web/20041029003853/http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q36">Matrix-FAQ Q36</a>
* @see <a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToMatrix/index.htm">euclideanspace.com-eulerToMatrix</a>
*/
- public static final void makeRotationEuler(final float bankX, final float headingY, final float attitudeZ, final float[] mat, final int mat_offset) {
+ public static float[] makeRotationEuler(final float[] m, final int m_offset, final float bankX, final float headingY, final float attitudeZ) {
// Assuming the angles are in radians.
final float ch = cos(headingY);
final float sh = sin(headingY);
@@ -180,32 +391,45 @@ public class FloatUtil {
final float cb = cos(bankX);
final float sb = sin(bankX);
- mat[0+0*4+mat_offset] = ch*ca;
- mat[0+1*4+mat_offset] = sh*sb - ch*sa*cb;
- mat[0+2*4+mat_offset] = ch*sa*sb + sh*cb;
- mat[1+0*4+mat_offset] = sa;
- mat[1+1*4+mat_offset] = ca*cb;
- mat[1+2*4+mat_offset] = -ca*sb;
- mat[2+0*4+mat_offset] = -sh*ca;
- mat[2+1*4+mat_offset] = sh*sa*cb + ch*sb;
- mat[2+2*4+mat_offset] = -sh*sa*sb + ch*cb;
+ m[0+0*4+m_offset] = ch*ca;
+ m[0+1*4+m_offset] = sh*sb - ch*sa*cb;
+ m[0+2*4+m_offset] = ch*sa*sb + sh*cb;
+ m[0+3*4+m_offset] = 0;
+
+ m[1+0*4+m_offset] = sa;
+ m[1+1*4+m_offset] = ca*cb;
+ m[1+2*4+m_offset] = -ca*sb;
+ m[1+3*4+m_offset] = 0;
+
+ m[2+0*4+m_offset] = -sh*ca;
+ m[2+1*4+m_offset] = sh*sa*cb + ch*sb;
+ m[2+2*4+m_offset] = -sh*sa*sb + ch*cb;
+ m[2+3*4+m_offset] = 0;
- mat[3+0*4+mat_offset] = 0;
- mat[3+1*4+mat_offset] = 0;
- mat[3+2*4+mat_offset] = 0;
+ m[3+0*4+m_offset] = 0;
+ m[3+1*4+m_offset] = 0;
+ m[3+2*4+m_offset] = 0;
+ m[3+3*4+m_offset] = 1;
- mat[0+3*4+mat_offset] = 0;
- mat[1+3*4+mat_offset] = 0;
- mat[2+3*4+mat_offset] = 0;
- mat[3+3*4+mat_offset] = 1;
+ return m;
}
/**
* Make given matrix the orthogonal matrix based on given parameters.
- *
- * @param a 4x4 matrix in column-major order (also result)
- * @param a_off
- * @param initA if true, given matrix will be initialized w/ identity matrix.
+ * <pre>
+ Ortho matrix (Column Order):
+ 2/dx 0 0 0
+ 0 2/dy 0 0
+ 0 0 2/dz 0
+ tx ty tz 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 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 orthogonal fields are set.
* @param left
* @param right
* @param bottom
@@ -214,18 +438,31 @@ public class FloatUtil {
* @param zFar
* @return given matrix for chaining
*/
- public static final float[] makeOrthof(final float[] a, final int a_off, final boolean initA,
- final float left, final float right,
- final float bottom, final float top,
- final float zNear, final float zFar) {
- if( initA ) {
- FloatUtil.makeIdentityf(a, a_off);
- }
- // Ortho matrix (Column Order):
- // 2/dx 0 0 0
- // 0 2/dy 0 0
- // 0 0 2/dz 0
- // tx ty tz 1
+ public static float[] makeOrtho(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) {
+ 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 dx=right-left;
final float dy=top-bottom;
final float dz=zFar-zNear;
@@ -233,22 +470,37 @@ public class FloatUtil {
final float ty=-1.0f*(top+bottom)/dy;
final float tz=-1.0f*(zFar+zNear)/dz;
- a[a_off+0+4*0] = 2.0f/dx;
- a[a_off+1+4*1] = 2.0f/dy;
- a[a_off+2+4*2] = -2.0f/dz;
- a[a_off+0+4*3] = tx;
- a[a_off+1+4*3] = ty;
- a[a_off+2+4*3] = tz;
+ m[m_offset+0+4*0] = 2.0f/dx;
- return a;
+ m[m_offset+1+4*1] = 2.0f/dy;
+
+ m[m_offset+2+4*2] = -2.0f/dz;
+
+ m[m_offset+0+4*3] = tx;
+ m[m_offset+1+4*3] = ty;
+ m[m_offset+2+4*3] = tz;
+ m[m_offset+3+4*3] = 1f;
+
+ 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 a 4x4 matrix in column-major order (also result)
- * @param a_off
- * @param initA if true, given matrix will be initialized w/ identity matrix.
+ * @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
@@ -257,24 +509,37 @@ public class FloatUtil {
* @param zFar
* @return given matrix for chaining
*/
- public static final float[] makeFrustumf(final float[] a, final int a_off, final boolean initA,
- final float left, final float right,
- final float bottom, final float top,
- final float zNear, final float zFar) {
+ 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) {
if(zNear<=0.0f||zFar<0.0f) {
throw new GLException("GL_INVALID_VALUE: zNear and zFar must be positive, and zNear>0");
}
if(left==right || top==bottom) {
throw new GLException("GL_INVALID_VALUE: top,bottom and left,right must not be equal");
}
- if( initA ) {
- FloatUtil.makeIdentityf(a, a_off);
+ 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;
}
- // Frustum matrix (Column Order):
- // 2*zNear/dx 0 0 0
- // 0 2*zNear/dy 0 0
- // A B C -1
- // 0 0 D 0
final float zNear2 = 2.0f*zNear;
final float dx=right-left;
final float dy=top-bottom;
@@ -284,37 +549,875 @@ public class FloatUtil {
final float C=-1.0f*(zFar+zNear)/dz;
final float D=-2.0f*(zFar*zNear)/dz;
- a[a_off+0+4*0] = zNear2/dx;
- a[a_off+1+4*1] = zNear2/dy;
- a[a_off+2+4*2] = C;
+ 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;
- a[a_off+0+4*2] = A;
- a[a_off+1+4*2] = B;
+ m[m_offset+2+4*3] = D;
+ m[m_offset+3+4*3] = 0f;
- a[a_off+2+4*3] = D;
- a[a_off+3+4*2] = -1.0f;
- return a;
+ return m;
}
/**
* Make given matrix the perspective matrix based on given parameters.
+ * <p>
+ * All matrix fields are only set if <code>initM</code> is <code>true</code>.
+ * </p>
*
- * @param a 4x4 matrix in column-major order (also result)
- * @param a_off
- * @param initA if true, given matrix will be initialized w/ identity matrix.
+ * @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 non-zero fields are set.
* @param fovy angle in radians
* @param aspect
* @param zNear
* @param zFar
* @return given matrix for chaining
*/
- public static final float[] makePerspective(final float[] a, final int a_off, final boolean initA,
- final float fovy, final float aspect, final float zNear, final float zFar) {
+ public static float[] makePerspective(final float[] m, final int m_off, final boolean initM,
+ final float fovy, final float aspect, final float zNear, final float zFar) {
float top=(float)Math.tan(fovy)*zNear;
float bottom=-1.0f*top;
float left=aspect*bottom;
float right=aspect*top;
- return makeFrustumf(a, a_off, initA, left, right, bottom, top, zNear, zFar);
+ 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 + 1 * 4 + 0] = mat4Tmp[1+side_off]; // side
+ m[m_offset + 2 * 4 + 0] = mat4Tmp[2+side_off]; // side
+ m[m_offset + 3 * 4 + 0] = 0;
+
+ m[m_offset + 0 * 4 + 1] = mat4Tmp[0+up2_off]; // up2
+ m[m_offset + 1 * 4 + 1] = mat4Tmp[1+up2_off]; // up2
+ m[m_offset + 2 * 4 + 1] = mat4Tmp[2+up2_off]; // up2
+ m[m_offset + 3 * 4 + 1] = 0;
+
+ m[m_offset + 0 * 4 + 2] = -mat4Tmp[0]; // forward
+ m[m_offset + 1 * 4 + 2] = -mat4Tmp[1]; // forward
+ m[m_offset + 2 * 4 + 2] = -mat4Tmp[2]; // forward
+ m[m_offset + 3 * 4 + 2] = 0;
+
+ m[m_offset + 0 * 4 + 3] = 0;
+ m[m_offset + 1 * 4 + 3] = 0;
+ m[m_offset + 2 * 4 + 3] = 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>
+ * 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
+ * @param y
+ * @param deltaX
+ * @param deltaY
+ * @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 int m_offset,
+ 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, m_offset, 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, m_offset, mat4Tmp, 0);
+ return m;
+ }
+
+ /**
+ * Transpose the given matrix.
+ *
+ * @param msrc 4x4 matrix in column-major order, the source
+ * @param msrc_offset offset in given array <i>msrc</i>, i.e. start of the 4x4 matrix
+ * @param mres 4x4 matrix in column-major order, the result - may be <code>msrc</code> (in-place)
+ * @param mres_offset offset in given array <i>mres</i>, i.e. start of the 4x4 matrix - may be <code>msrc_offset</code> (in-place)
+ * @return given result matrix <i>mres</i> for chaining
+ */
+ public static float[] transposeMatrix(final float[] msrc, final int msrc_offset, final float[] mres, final int mres_offset) {
+ for (int i = 0; i < 4; i++) {
+ final int i4 = i*4;
+ for (int j = 0; j < 4; j++) {
+ mres[mres_offset+j+i4] = msrc[msrc_offset+i+j*4];
+ }
+ }
+ return mres;
+ }
+
+ /**
+ * Transpose the given matrix in place.
+ *
+ * @param m 4x4 matrix in column-major order, the source
+ * @param m_offset offset in given array <i>msrc</i>, i.e. start of the 4x4 matrix
+ * @param temp temporary 4*4 float storage
+ * @return given result matrix <i>m</i> for chaining
+ */
+ public static float[] transposeMatrix(final float[] m, final int m_offset, final float[/*4*4*/] temp) {
+ int i, j;
+ for (i = 0; i < 4; i++) {
+ final int i4 = i*4;
+ for (j = 0; j < 4; j++) {
+ temp[i4+j] = m[i4+j+m_offset];
+ }
+ }
+ for (i = 0; i < 4; i++) {
+ final int i4 = i*4;
+ for (j = 0; j < 4; j++) {
+ m[m_offset+j+i4] = temp[i+j*4];
+ }
+ }
+ 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 - may be <code>msrc</code> (in-place)
+ * @return given result matrix <i>mres</i> for chaining
+ */
+ public static FloatBuffer transposeMatrix(final FloatBuffer msrc, final FloatBuffer mres) {
+ final int msrc_offset = msrc.position();
+ final int mres_offset = mres.position();
+ for (int i = 0; i < 4; i++) {
+ final int i4 = i*4;
+ for (int j = 0; j < 4; j++) {
+ mres.put(mres_offset+j+i4, msrc.get(msrc_offset+i+j*4));
+ }
+ }
+ return mres;
+ }
+
+ /**
+ * Transpose the given matrix in place.
+ *
+ * @param m 4x4 matrix in column-major order, the source
+ * @param temp temporary 4*4 float storage
+ * @return given matrix <i>m</i> for chaining
+ */
+ public static FloatBuffer transposeMatrix(FloatBuffer m, final float[/*4*4*/] temp) {
+ final int m_offset = m.position();
+ int i, j;
+ for (i = 0; i < 4; i++) {
+ final int i4 = i*4;
+ for (j = 0; j < 4; j++) {
+ temp[i4+j] = m.get(i4+j+m_offset);
+ }
+ }
+ for (i = 0; i < 4; i++) {
+ final int i4 = i*4;
+ for (j = 0; j < 4; j++) {
+ m.put(m_offset+j+i4, temp[i+j*4]);
+ }
+ }
+ return m;
+ }
+
+ /**
+ * 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 msrc_offset offset in given array <i>msrc</i>, i.e. start of the 4x4 matrix
+ * @param mres 4x4 matrix in column-major order, the result - may be <code>msrc</code> (in-place)
+ * @param mres_offset offset in given array <i>mres</i>, i.e. start of the 4x4 matrix - may be <code>msrc_offset</code> (in-place)
+ * @param temp temporary 4*4 float storage
+ * @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 int msrc_offset, final float[] mres, final int mres_offset, final float[/*4*4*/] temp) {
+ int i, j, k, swap;
+ float t;
+ for (i = 0; i < 4; i++) {
+ final int i4 = i*4;
+ for (j = 0; j < 4; j++) {
+ temp[i4+j] = msrc[i4+j+msrc_offset];
+ }
+ }
+ makeIdentity(mres, mres_offset);
+
+ for (i = 0; i < 4; i++) {
+ final int i4 = i*4;
+
+ //
+ // Look for largest element in column
+ //
+ swap = i;
+ for (j = i + 1; j < 4; j++) {
+ if (Math.abs(temp[j*4+i]) > Math.abs(temp[i4+i])) {
+ swap = j;
+ }
+ }
+
+ if (swap != i) {
+ final int swap4 = swap*4;
+ //
+ // Swap rows.
+ //
+ for (k = 0; k < 4; k++) {
+ t = temp[i4+k];
+ temp[i4+k] = temp[swap4+k];
+ temp[swap4+k] = t;
+
+ t = mres[i4+k+mres_offset];
+ mres[i4+k+mres_offset] = mres[swap4+k+mres_offset];
+ mres[swap4+k+mres_offset] = t;
+ }
+ }
+
+ if (temp[i4+i] == 0) {
+ //
+ // No non-zero pivot. The matrix is singular, which shouldn't
+ // happen. This means the user gave us a bad matrix.
+ //
+ return null;
+ }
+
+ t = temp[i4+i];
+ for (k = 0; k < 4; k++) {
+ temp[i4+k] /= t;
+ mres[i4+k+mres_offset] /= t;
+ }
+ for (j = 0; j < 4; j++) {
+ if (j != i) {
+ final int j4 = j*4;
+ t = temp[j4+i];
+ for (k = 0; k < 4; k++) {
+ temp[j4+k] -= temp[i4+k] * t;
+ mres[j4+k+mres_offset] -= mres[i4+k+mres_offset]*t;
+ }
+ }
+ }
+ }
+ return mres;
+ }
+
+ /**
+ * 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)
+ * @param temp temporary 4*4 float storage
+ * @return given result matrix <i>mres</i> for chaining if successful, otherwise <code>null</code>. See above.
+ */
+ public static FloatBuffer invertMatrix(final FloatBuffer msrc, final FloatBuffer mres, final float[/*4*4*/] temp) {
+ int i, j, k, swap;
+ float t;
+
+ final int msrc_offset = msrc.position();
+ final int mres_offset = mres.position();
+
+ for (i = 0; i < 4; i++) {
+ final int i4 = i*4;
+ for (j = 0; j < 4; j++) {
+ temp[i4+j] = msrc.get(i4+j + msrc_offset);
+ }
+ }
+ makeIdentity(mres);
+
+ for (i = 0; i < 4; i++) {
+ final int i4 = i*4;
+
+ //
+ // Look for largest element in column
+ //
+ swap = i;
+ for (j = i + 1; j < 4; j++) {
+ if (Math.abs(temp[j*4+i]) > Math.abs(temp[i4+i])) {
+ swap = j;
+ }
+ }
+
+ if (swap != i) {
+ final int swap4 = swap*4;
+ //
+ // Swap rows.
+ //
+ for (k = 0; k < 4; k++) {
+ t = temp[i4+k];
+ temp[i4+k] = temp[swap4+k];
+ temp[swap4+k] = t;
+
+ t = mres.get(i4+k + mres_offset);
+ mres.put(i4+k + mres_offset, mres.get(swap4+k + mres_offset));
+ mres.put(swap4+k + mres_offset, t);
+ }
+ }
+
+ if (temp[i4+i] == 0) {
+ //
+ // No non-zero pivot. The matrix is singular, which shouldn't
+ // happen. This means the user gave us a bad matrix.
+ //
+ return null;
+ }
+
+ t = temp[i4+i];
+ for (k = 0; k < 4; k++) {
+ temp[i4+k] /= t;
+ final int z = i4+k + mres_offset;
+ mres.put(z, mres.get(z) / t);
+ }
+ for (j = 0; j < 4; j++) {
+ if (j != i) {
+ final int j4 = j*4;
+ t = temp[j4+i];
+ for (k = 0; k < 4; k++) {
+ temp[j4+k] -= temp[i4+k] * t;
+ final int z = j4+k + mres_offset;
+ mres.put(z, mres.get(z) - mres.get(i4+k + mres_offset) * t);
+ }
+ }
+ }
+ }
+ 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 mapObjToWinCoords(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, 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 object coordinates to window coordinates.
+ * <p>
+ * Traditional <code>gluProject</code> implementation.
+ * </p>
+ *
+ * @param objx
+ * @param objy
+ * @param objz
+ * @param mat4PMv [projection] x [modelview] matrix, i.e. P x Mv
+ * @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 mapObjToWinCoords(final float objx, final float objy, final float objz,
+ final float[/*16*/] mat4PMv,
+ final int[] viewport, final int viewport_offset,
+ final float[] win_pos, int win_pos_offset,
+ final float[/*4*/] vec4Tmp1, final float[/*4*/] vec4Tmp2) {
+ vec4Tmp2[0] = objx;
+ vec4Tmp2[1] = objy;
+ vec4Tmp2[2] = objz;
+ vec4Tmp2[3] = 1.0f;
+
+ // vec4Tmp1 = P * Mv * o
+ multMatrixVec(mat4PMv, vec4Tmp2, vec4Tmp1);
+
+ 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 mapWinToObjCoords(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, 0, mat4Tmp1, 0, mat4Tmp2) ) {
+ 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>gluUnProject</code> implementation.
+ * </p>
+ *
+ * @param winx
+ * @param winy
+ * @param winz
+ * @param mat4PMvI inverse [projection] x [modelview] matrix, i.e. Inv(P x Mv)
+ * @param viewport 4 component viewport vector
+ * @param viewport_offset
+ * @param obj_pos 3 component object coordinate, the result
+ * @param obj_pos_offset
+ * @param vec4Tmp1 4 component vector for temp storage
+ * @param vec4Tmp2 4 component vector for temp storage
+ * @return true if successful, otherwise false (failed to invert matrix, or becomes infinity due to zero z)
+ */
+ public static boolean mapWinToObjCoords(final float winx, final float winy, final float winz,
+ final float[/*16*/] mat4PMvI,
+ final int[] viewport, final int viewport_offset,
+ final float[] obj_pos, final int obj_pos_offset,
+ final float[/*4*/] vec4Tmp1, final float[/*4*/] vec4Tmp2) {
+ vec4Tmp1[0] = winx;
+ vec4Tmp1[1] = winy;
+ vec4Tmp1[2] = winz;
+ vec4Tmp1[3] = 1.0f;
+
+ // Map x and y from window coordinates
+ vec4Tmp1[0] = (vec4Tmp1[0] - viewport[0+viewport_offset]) / viewport[2+viewport_offset];
+ vec4Tmp1[1] = (vec4Tmp1[1] - viewport[1+viewport_offset]) / viewport[3+viewport_offset];
+
+ // Map to range -1 to 1
+ vec4Tmp1[0] = vec4Tmp1[0] * 2 - 1;
+ vec4Tmp1[1] = vec4Tmp1[1] * 2 - 1;
+ vec4Tmp1[2] = vec4Tmp1[2] * 2 - 1;
+
+ // object raw coords = Inv(P x Mv) * winPos -> mat4Tmp2
+ multMatrixVec(mat4PMvI, vec4Tmp1, vec4Tmp2);
+
+ if (vec4Tmp2[3] == 0.0) {
+ return false;
+ }
+
+ vec4Tmp2[3] = 1.0f / vec4Tmp2[3];
+
+ obj_pos[0+obj_pos_offset] = vec4Tmp2[0] * vec4Tmp2[3];
+ obj_pos[1+obj_pos_offset] = vec4Tmp2[1] * vec4Tmp2[3];
+ obj_pos[2+obj_pos_offset] = vec4Tmp2[2] * vec4Tmp2[3];
+
+ return true;
+ }
+
+ /**
+ * Map two window coordinates to two object coordinates,
+ * distinguished by their z component.
+ *
+ * @param winx
+ * @param winy
+ * @param winz1
+ * @param winz2
+ * @param mat4PMvI inverse [projection] x [modelview] matrix, i.e. Inv(P x Mv)
+ * @param viewport 4 component viewport vector
+ * @param viewport_offset
+ * @param obj1_pos 3 component object coordinate, the result for winz1
+ * @param obj1_pos_offset
+ * @param obj2_pos 3 component object coordinate, the result for winz2
+ * @param obj2_pos_offset
+ * @param vec4Tmp1 4 component vector for temp storage
+ * @param vec4Tmp2 4 component vector for temp storage
+ * @return true if successful, otherwise false (failed to invert matrix, or becomes infinity due to zero z)
+ */
+ public static boolean mapWinToObjCoords(final float winx, final float winy, final float winz1, final float winz2,
+ final float[/*16*/] mat4PMvI,
+ final int[] viewport, final int viewport_offset,
+ final float[] obj1_pos, final int obj1_pos_offset,
+ final float[] obj2_pos, final int obj2_pos_offset,
+ final float[/*4*/] vec4Tmp1, final float[/*4*/] vec4Tmp2) {
+ vec4Tmp1[0] = winx;
+ vec4Tmp1[1] = winy;
+ vec4Tmp1[3] = 1.0f;
+
+ // Map x and y from window coordinates
+ vec4Tmp1[0] = (vec4Tmp1[0] - viewport[0+viewport_offset]) / viewport[2+viewport_offset];
+ vec4Tmp1[1] = (vec4Tmp1[1] - viewport[1+viewport_offset]) / viewport[3+viewport_offset];
+
+ // Map to range -1 to 1
+ vec4Tmp1[0] = vec4Tmp1[0] * 2 - 1;
+ vec4Tmp1[1] = vec4Tmp1[1] * 2 - 1;
+
+ //
+ // winz1
+ //
+ vec4Tmp1[2] = winz1;
+ vec4Tmp1[2] = vec4Tmp1[2] * 2 - 1;
+
+ // object raw coords = Inv(P x Mv) * winPos -> mat4Tmp2
+ multMatrixVec(mat4PMvI, vec4Tmp1, vec4Tmp2);
+
+ if (vec4Tmp2[3] == 0.0) {
+ return false;
+ }
+
+ vec4Tmp2[3] = 1.0f / vec4Tmp2[3];
+
+ obj1_pos[0+obj1_pos_offset] = vec4Tmp2[0] * vec4Tmp2[3];
+ obj1_pos[1+obj1_pos_offset] = vec4Tmp2[1] * vec4Tmp2[3];
+ obj1_pos[2+obj1_pos_offset] = vec4Tmp2[2] * vec4Tmp2[3];
+
+ //
+ // winz2
+ //
+ vec4Tmp1[2] = winz2;
+ vec4Tmp1[2] = vec4Tmp1[2] * 2 - 1;
+
+ // object raw coords = Inv(P x Mv) * winPos -> mat4Tmp2
+ multMatrixVec(mat4PMvI, vec4Tmp1, vec4Tmp2);
+
+ if (vec4Tmp2[3] == 0.0) {
+ return false;
+ }
+
+ vec4Tmp2[3] = 1.0f / vec4Tmp2[3];
+
+ obj2_pos[0+obj2_pos_offset] = vec4Tmp2[0] * vec4Tmp2[3];
+ obj2_pos[1+obj2_pos_offset] = vec4Tmp2[1] * vec4Tmp2[3];
+ obj2_pos[2+obj2_pos_offset] = vec4Tmp2[2] * vec4Tmp2[3];
+
+ 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 mapWinToObjCoords(final float winx, final float winy, final float winz, final float clipw,
+ float[] modelMatrix, int modelMatrix_offset,
+ float[] projMatrix, int projMatrix_offset,
+ int[] viewport, int viewport_offset,
+ float near, float far,
+ float[] obj_pos, 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, 0, mat4Tmp1, 0, mat4Tmp2) ) {
+ 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];
+ 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;
+ }
+
+ mat4Tmp2[3+raw_off] = 1.0f / mat4Tmp2[3+raw_off];
+
+ 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;
+ }
+
+
+ /**
+ * Map two window coordinates w/ shared X/Y and distinctive Z
+ * to a {@link Ray}. The resulting {@link Ray} maybe used for <i>picking</i>
+ * using a {@link AABBox#getRayIntersection(Ray, float[]) bounding box}.
+ * <p>
+ * Notes for picking <i>winz0</i> and <i>winz1</i>:
+ * <ul>
+ * <li>see {@link #getZBufferEpsilon(int, float, float)}</li>
+ * <li>see {@link #getZBufferValue(int, float, float, float)}</li>
+ * <li>see {@link #getOrthoWinZ(float, float, float)}</li>
+ * </ul>
+ * </p>
+ * @param winx
+ * @param winy
+ * @param winz0
+ * @param winz1
+ * @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 ray storage for the resulting {@link Ray}
+ * @param mat4Tmp1 16 component matrix for temp storage
+ * @param mat4Tmp2 16 component matrix for temp storage
+ * @param vec4Tmp2 4 component vector for temp storage
+ * @return true if successful, otherwise false (failed to invert matrix, or becomes z is infinity)
+ */
+ public static boolean mapWinToRay(final float winx, final float winy, final float winz0, final float winz1,
+ final float[] modelMatrix, final int modelMatrix_offset,
+ final float[] projMatrix, final int projMatrix_offset,
+ final int[] viewport, final int viewport_offset,
+ final Ray ray,
+ final float[/*16*/] mat4Tmp1, final float[/*16*/] mat4Tmp2, final float[/*4*/] vec4Tmp2) {
+ // mat4Tmp1 = P x Mv
+ multMatrix(projMatrix, projMatrix_offset, modelMatrix, modelMatrix_offset, mat4Tmp1, 0);
+
+ // mat4Tmp1 = Inv(P x Mv)
+ if ( null == invertMatrix(mat4Tmp1, 0, mat4Tmp1, 0, mat4Tmp2) ) {
+ return false;
+ }
+ if( mapWinToObjCoords(winx, winy, winz0, winz1, mat4Tmp1,
+ viewport, viewport_offset,
+ ray.orig, 0, ray.dir, 0,
+ mat4Tmp2, vec4Tmp2) ) {
+ VectorUtil.normalizeVec3( VectorUtil.subVec3(ray.dir, ray.dir, ray.orig) );
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * 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, float[] d, final int d_off) {
+ for (int i = 0; i < 4; i++) {
+ // one row in column-major order
+ final int a_off_i = a_off+i;
+ final int d_off_i = d_off+i;
+ final float ai0=a[a_off_i+0*4], ai1=a[a_off_i+1*4], ai2=a[a_off_i+2*4], ai3=a[a_off_i+3*4]; // row-i of a
+ d[d_off_i+0*4] = ai0 * b[b_off+0+0*4] + ai1 * b[b_off+1+0*4] + ai2 * b[b_off+2+0*4] + ai3 * b[b_off+3+0*4] ;
+ d[d_off_i+1*4] = ai0 * b[b_off+0+1*4] + ai1 * b[b_off+1+1*4] + ai2 * b[b_off+2+1*4] + ai3 * b[b_off+3+1*4] ;
+ d[d_off_i+2*4] = ai0 * b[b_off+0+2*4] + ai1 * b[b_off+1+2*4] + ai2 * b[b_off+2+2*4] + ai3 * b[b_off+3+2*4] ;
+ d[d_off_i+3*4] = ai0 * b[b_off+0+3*4] + ai1 * b[b_off+1+3*4] + ai2 * b[b_off+2+3*4] + ai3 * b[b_off+3+3*4] ;
+ }
}
/**
@@ -323,14 +1426,14 @@ public class FloatUtil {
* @param b 4x4 matrix in column-major order
* @param d result a*b in column-major order
*/
- public static final void multMatrixf(final float[] a, int a_off, final float[] b, int b_off, float[] d, int d_off) {
+ public static void multMatrix(final float[] a, final float[] b, float[] d) {
for (int i = 0; i < 4; i++) {
// one row in column-major order
- final float ai0=a[a_off+i+0*4], ai1=a[a_off+i+1*4], ai2=a[a_off+i+2*4], ai3=a[a_off+i+3*4]; // row-i of a
- d[d_off+i+0*4] = ai0 * b[b_off+0+0*4] + ai1 * b[b_off+1+0*4] + ai2 * b[b_off+2+0*4] + ai3 * b[b_off+3+0*4] ;
- d[d_off+i+1*4] = ai0 * b[b_off+0+1*4] + ai1 * b[b_off+1+1*4] + ai2 * b[b_off+2+1*4] + ai3 * b[b_off+3+1*4] ;
- d[d_off+i+2*4] = ai0 * b[b_off+0+2*4] + ai1 * b[b_off+1+2*4] + ai2 * b[b_off+2+2*4] + ai3 * b[b_off+3+2*4] ;
- d[d_off+i+3*4] = ai0 * b[b_off+0+3*4] + ai1 * b[b_off+1+3*4] + ai2 * b[b_off+2+3*4] + ai3 * b[b_off+3+3*4] ;
+ final float ai0=a[i+0*4], ai1=a[i+1*4], ai2=a[i+2*4], ai3=a[i+3*4]; // row-i of a
+ d[i+0*4] = ai0 * b[0+0*4] + ai1 * b[1+0*4] + ai2 * b[2+0*4] + ai3 * b[3+0*4] ;
+ d[i+1*4] = ai0 * b[0+1*4] + ai1 * b[1+1*4] + ai2 * b[2+1*4] + ai3 * b[3+1*4] ;
+ d[i+2*4] = ai0 * b[0+2*4] + ai1 * b[1+2*4] + ai2 * b[2+2*4] + ai3 * b[3+2*4] ;
+ d[i+3*4] = ai0 * b[0+3*4] + ai1 * b[1+3*4] + ai2 * b[2+3*4] + ai3 * b[3+3*4] ;
}
}
@@ -339,7 +1442,7 @@ public class FloatUtil {
* @param a 4x4 matrix in column-major order (also result)
* @param b 4x4 matrix in column-major order
*/
- public static final void multMatrixf(final float[] a, int a_off, final float[] b, int b_off) {
+ public static void multMatrix(final float[] a, final int a_off, final float[] b, final int b_off) {
for (int i = 0; i < 4; i++) {
// one row in column-major order
final int a_off_i = a_off+i;
@@ -352,20 +1455,38 @@ public class FloatUtil {
}
/**
+ * 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 float[] b) {
+ for (int i = 0; i < 4; i++) {
+ // one row in column-major order
+ final float ai0=a[i+0*4], ai1=a[i+1*4], ai2=a[i+2*4], ai3=a[i+3*4]; // row-i of a
+ a[i+0*4] = ai0 * b[0+0*4] + ai1 * b[1+0*4] + ai2 * b[2+0*4] + ai3 * b[3+0*4] ;
+ a[i+1*4] = ai0 * b[0+1*4] + ai1 * b[1+1*4] + ai2 * b[2+1*4] + ai3 * b[3+1*4] ;
+ a[i+2*4] = ai0 * b[0+2*4] + ai1 * b[1+2*4] + ai2 * b[2+2*4] + ai3 * b[3+2*4] ;
+ a[i+3*4] = ai0 * b[0+3*4] + ai1 * b[1+3*4] + ai2 * b[2+3*4] + ai3 * b[3+3*4] ;
+ }
+ }
+
+ /**
* 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 final void multMatrixf(final float[] a, int a_off, final float[] b, int b_off, FloatBuffer d) {
- final int dP = d.position();
+ public static void multMatrix(final float[] a, final int a_off, final float[] b, final int b_off, final FloatBuffer d) {
+ final int d_off = d.position();
for (int i = 0; i < 4; i++) {
// one row in column-major order
- final float ai0=a[a_off+i+0*4], ai1=a[a_off+i+1*4], ai2=a[a_off+i+2*4], ai3=a[a_off+i+3*4]; // row-i of a
- d.put(dP+i+0*4 , ai0 * b[b_off+0+0*4] + ai1 * b[b_off+1+0*4] + ai2 * b[b_off+2+0*4] + ai3 * b[b_off+3+0*4] );
- d.put(dP+i+1*4 , ai0 * b[b_off+0+1*4] + ai1 * b[b_off+1+1*4] + ai2 * b[b_off+2+1*4] + ai3 * b[b_off+3+1*4] );
- d.put(dP+i+2*4 , ai0 * b[b_off+0+2*4] + ai1 * b[b_off+1+2*4] + ai2 * b[b_off+2+2*4] + ai3 * b[b_off+3+2*4] );
- d.put(dP+i+3*4 , ai0 * b[b_off+0+3*4] + ai1 * b[b_off+1+3*4] + ai2 * b[b_off+2+3*4] + ai3 * b[b_off+3+3*4] );
+ final int a_off_i = a_off+i;
+ final int d_off_i = d_off+i;
+ final float ai0=a[a_off_i+0*4], ai1=a[a_off_i+1*4], ai2=a[a_off_i+2*4], ai3=a[a_off_i+3*4]; // row-i of a
+ d.put(d_off_i+0*4 , ai0 * b[b_off+0+0*4] + ai1 * b[b_off+1+0*4] + ai2 * b[b_off+2+0*4] + ai3 * b[b_off+3+0*4] );
+ d.put(d_off_i+1*4 , ai0 * b[b_off+0+1*4] + ai1 * b[b_off+1+1*4] + ai2 * b[b_off+2+1*4] + ai3 * b[b_off+3+1*4] );
+ d.put(d_off_i+2*4 , ai0 * b[b_off+0+2*4] + ai1 * b[b_off+1+2*4] + ai2 * b[b_off+2+2*4] + ai3 * b[b_off+3+2*4] );
+ d.put(d_off_i+3*4 , ai0 * b[b_off+0+3*4] + ai1 * b[b_off+1+3*4] + ai2 * b[b_off+2+3*4] + ai3 * b[b_off+3+3*4] );
}
}
@@ -375,16 +1496,18 @@ public class FloatUtil {
* @param b 4x4 matrix in column-major order
* @param d result a*b in column-major order
*/
- public static final void multMatrixf(final FloatBuffer a, final float[] b, int b_off, FloatBuffer d) {
- final int aP = a.position();
- final int dP = d.position();
+ public static void multMatrix(final FloatBuffer a, final float[] b, final int b_off, final FloatBuffer d) {
+ final int a_off = a.position();
+ final int d_off = d.position();
for (int i = 0; i < 4; i++) {
// one row in column-major order
- final float ai0=a.get(aP+i+0*4), ai1=a.get(aP+i+1*4), ai2=a.get(aP+i+2*4), ai3=a.get(aP+i+3*4); // row-i of a
- d.put(dP+i+0*4 , ai0 * b[b_off+0+0*4] + ai1 * b[b_off+1+0*4] + ai2 * b[b_off+2+0*4] + ai3 * b[b_off+3+0*4] );
- d.put(dP+i+1*4 , ai0 * b[b_off+0+1*4] + ai1 * b[b_off+1+1*4] + ai2 * b[b_off+2+1*4] + ai3 * b[b_off+3+1*4] );
- d.put(dP+i+2*4 , ai0 * b[b_off+0+2*4] + ai1 * b[b_off+1+2*4] + ai2 * b[b_off+2+2*4] + ai3 * b[b_off+3+2*4] );
- d.put(dP+i+3*4 , ai0 * b[b_off+0+3*4] + ai1 * b[b_off+1+3*4] + ai2 * b[b_off+2+3*4] + ai3 * b[b_off+3+3*4] );
+ final int a_off_i = a_off+i;
+ final int d_off_i = d_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.put(d_off_i+0*4 , ai0 * b[b_off+0+0*4] + ai1 * b[b_off+1+0*4] + ai2 * b[b_off+2+0*4] + ai3 * b[b_off+3+0*4] );
+ d.put(d_off_i+1*4 , ai0 * b[b_off+0+1*4] + ai1 * b[b_off+1+1*4] + ai2 * b[b_off+2+1*4] + ai3 * b[b_off+3+1*4] );
+ d.put(d_off_i+2*4 , ai0 * b[b_off+0+2*4] + ai1 * b[b_off+1+2*4] + ai2 * b[b_off+2+2*4] + ai3 * b[b_off+3+2*4] );
+ d.put(d_off_i+3*4 , ai0 * b[b_off+0+3*4] + ai1 * b[b_off+1+3*4] + ai2 * b[b_off+2+3*4] + ai3 * b[b_off+3+3*4] );
}
}
@@ -393,16 +1516,16 @@ public class FloatUtil {
* @param a 4x4 matrix in column-major order (also result)
* @param b 4x4 matrix in column-major order
*/
- public static final void multMatrixf(final FloatBuffer a, final float[] b, int b_off) {
- final int aP = a.position();
+ public static void multMatrix(final FloatBuffer a, final float[] b, final int b_off) {
+ final int a_off = a.position();
for (int i = 0; i < 4; i++) {
// one row in column-major order
- final int aP_i = aP+i;
- final float ai0=a.get(aP_i+0*4), ai1=a.get(aP_i+1*4), ai2=a.get(aP_i+2*4), ai3=a.get(aP_i+3*4); // row-i of a
- a.put(aP_i+0*4 , ai0 * b[b_off+0+0*4] + ai1 * b[b_off+1+0*4] + ai2 * b[b_off+2+0*4] + ai3 * b[b_off+3+0*4] );
- a.put(aP_i+1*4 , ai0 * b[b_off+0+1*4] + ai1 * b[b_off+1+1*4] + ai2 * b[b_off+2+1*4] + ai3 * b[b_off+3+1*4] );
- a.put(aP_i+2*4 , ai0 * b[b_off+0+2*4] + ai1 * b[b_off+1+2*4] + ai2 * b[b_off+2+2*4] + ai3 * b[b_off+3+2*4] );
- a.put(aP_i+3*4 , ai0 * b[b_off+0+3*4] + ai1 * b[b_off+1+3*4] + ai2 * b[b_off+2+3*4] + ai3 * b[b_off+3+3*4] );
+ 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[b_off+0+0*4] + ai1 * b[b_off+1+0*4] + ai2 * b[b_off+2+0*4] + ai3 * b[b_off+3+0*4] );
+ a.put(a_off_i+1*4 , ai0 * b[b_off+0+1*4] + ai1 * b[b_off+1+1*4] + ai2 * b[b_off+2+1*4] + ai3 * b[b_off+3+1*4] );
+ a.put(a_off_i+2*4 , ai0 * b[b_off+0+2*4] + ai1 * b[b_off+1+2*4] + ai2 * b[b_off+2+2*4] + ai3 * b[b_off+3+2*4] );
+ a.put(a_off_i+3*4 , ai0 * b[b_off+0+3*4] + ai1 * b[b_off+1+3*4] + ai2 * b[b_off+2+3*4] + ai3 * b[b_off+3+3*4] );
}
}
@@ -412,17 +1535,19 @@ public class FloatUtil {
* @param b 4x4 matrix in column-major order
* @param d result a*b in column-major order
*/
- public static final void multMatrixf(final FloatBuffer a, final FloatBuffer b, FloatBuffer d) {
- final int aP = a.position();
- final int bP = b.position();
- final int dP = d.position();
+ public static void multMatrix(final FloatBuffer a, final FloatBuffer b, final FloatBuffer d) {
+ final int a_off = a.position();
+ final int b_off = b.position();
+ final int d_off = d.position();
for (int i = 0; i < 4; i++) {
// one row in column-major order
- final float ai0=a.get(aP+i+0*4), ai1=a.get(aP+i+1*4), ai2=a.get(aP+i+2*4), ai3=a.get(aP+i+3*4); // row-i of a
- d.put(dP+i+0*4 , ai0 * b.get(bP+0+0*4) + ai1 * b.get(bP+1+0*4) + ai2 * b.get(bP+2+0*4) + ai3 * b.get(bP+3+0*4) );
- d.put(dP+i+1*4 , ai0 * b.get(bP+0+1*4) + ai1 * b.get(bP+1+1*4) + ai2 * b.get(bP+2+1*4) + ai3 * b.get(bP+3+1*4) );
- d.put(dP+i+2*4 , ai0 * b.get(bP+0+2*4) + ai1 * b.get(bP+1+2*4) + ai2 * b.get(bP+2+2*4) + ai3 * b.get(bP+3+2*4) );
- d.put(dP+i+3*4 , ai0 * b.get(bP+0+3*4) + ai1 * b.get(bP+1+3*4) + ai2 * b.get(bP+2+3*4) + ai3 * b.get(bP+3+3*4) );
+ final int a_off_i = a_off+i;
+ final int d_off_i = d_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.put(d_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) );
+ d.put(d_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) );
+ d.put(d_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) );
+ d.put(d_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) );
}
}
@@ -431,17 +1556,17 @@ public class FloatUtil {
* @param a 4x4 matrix in column-major order (also result)
* @param b 4x4 matrix in column-major order
*/
- public static final void multMatrixf(final FloatBuffer a, final FloatBuffer b) {
- final int aP = a.position();
- final int bP = b.position();
+ 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 aP_i = aP+i;
- final float ai0=a.get(aP_i+0*4), ai1=a.get(aP_i+1*4), ai2=a.get(aP_i+2*4), ai3=a.get(aP_i+3*4); // row-i of a
- a.put(aP_i+0*4 , ai0 * b.get(bP+0+0*4) + ai1 * b.get(bP+1+0*4) + ai2 * b.get(bP+2+0*4) + ai3 * b.get(bP+3+0*4) );
- a.put(aP_i+1*4 , ai0 * b.get(bP+0+1*4) + ai1 * b.get(bP+1+1*4) + ai2 * b.get(bP+2+1*4) + ai3 * b.get(bP+3+1*4) );
- a.put(aP_i+2*4 , ai0 * b.get(bP+0+2*4) + ai1 * b.get(bP+1+2*4) + ai2 * b.get(bP+2+2*4) + ai3 * b.get(bP+3+2*4) );
- a.put(aP_i+3*4 , ai0 * b.get(bP+0+3*4) + ai1 * b.get(bP+1+3*4) + ai2 * b.get(bP+2+3*4) + ai3 * b.get(bP+3+3*4) );
+ 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) );
}
}
@@ -451,16 +1576,38 @@ public class FloatUtil {
* @param b 4x4 matrix in column-major order
* @param d result a*b in column-major order
*/
- public static final void multMatrixf(final FloatBuffer a, final FloatBuffer b, float[] d, int d_off) {
- final int aP = a.position();
- final int bP = b.position();
+ public static void multMatrix(final FloatBuffer a, final FloatBuffer b, final float[] d, final int d_off) {
+ 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 float ai0=a.get(aP+i+0*4), ai1=a.get(aP+i+1*4), ai2=a.get(aP+i+2*4), ai3=a.get(aP+i+3*4); // row-i of a
- d[d_off+i+0*4] = ai0 * b.get(bP+0+0*4) + ai1 * b.get(bP+1+0*4) + ai2 * b.get(bP+2+0*4) + ai3 * b.get(bP+3+0*4) ;
- d[d_off+i+1*4] = ai0 * b.get(bP+0+1*4) + ai1 * b.get(bP+1+1*4) + ai2 * b.get(bP+2+1*4) + ai3 * b.get(bP+3+1*4) ;
- d[d_off+i+2*4] = ai0 * b.get(bP+0+2*4) + ai1 * b.get(bP+1+2*4) + ai2 * b.get(bP+2+2*4) + ai3 * b.get(bP+3+2*4) ;
- d[d_off+i+3*4] = ai0 * b.get(bP+0+3*4) + ai1 * b.get(bP+1+3*4) + ai2 * b.get(bP+2+3*4) + ai3 * b.get(bP+3+3*4) ;
+ final int a_off_i = a_off+i;
+ final int d_off_i = d_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[d_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) ;
+ d[d_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) ;
+ d[d_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) ;
+ d[d_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) ;
+ }
+ }
+
+ /**
+ * 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) ;
}
}
@@ -470,14 +1617,17 @@ public class FloatUtil {
* @param v_in 4-component column-vector
* @param v_out m_in * v_in
*/
- public static final void multMatrixVecf(float[] m_in, int m_in_off, float[] v_in, int v_in_off, float[] v_out, int v_out_off) {
+ 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) {
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_out_off] =
- v_in[0+v_in_off] * m_in[0*4+i+m_in_off] +
- v_in[1+v_in_off] * m_in[1*4+i+m_in_off] +
- v_in[2+v_in_off] * m_in[2*4+i+m_in_off] +
- v_in[3+v_in_off] * m_in[3*4+i+m_in_off];
+ v_in[0+v_in_off] * m_in[0*4+i_m_in_off] +
+ v_in[1+v_in_off] * m_in[1*4+i_m_in_off] +
+ v_in[2+v_in_off] * m_in[2*4+i_m_in_off] +
+ v_in[3+v_in_off] * m_in[3*4+i_m_in_off];
}
}
@@ -487,7 +1637,7 @@ public class FloatUtil {
* @param v_in 4-component column-vector
* @param v_out m_in * v_in
*/
- public static final void multMatrixVecf(float[] m_in, float[] v_in, float[] v_out) {
+ public static void multMatrixVec(final float[] m_in, final float[] v_in, final float[] v_out) {
for (int i = 0; i < 4; i++) {
// (one matrix row in column-major order) X (column vector)
v_out[i] =
@@ -503,15 +1653,16 @@ public class FloatUtil {
* @param v_in 4-component column-vector
* @param v_out m_in * v_in
*/
- public static final void multMatrixVecf(FloatBuffer m_in, float[] v_in, int v_in_off, float[] v_out, int v_out_off) {
- final int matrixPos = m_in.position();
+ public static void multMatrixVec(final FloatBuffer m_in, final float[] v_in, final int v_in_off, final float[] v_out, final int v_out_off) {
+ 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_out_off] =
- v_in[0+v_in_off] * m_in.get(0*4+i+matrixPos) +
- v_in[1+v_in_off] * m_in.get(1*4+i+matrixPos) +
- v_in[2+v_in_off] * m_in.get(2*4+i+matrixPos) +
- v_in[3+v_in_off] * m_in.get(3*4+i+matrixPos);
+ v_in[0+v_in_off] * m_in.get(0*4+i_m_in_off) +
+ v_in[1+v_in_off] * m_in.get(1*4+i_m_in_off) +
+ v_in[2+v_in_off] * m_in.get(2*4+i_m_in_off) +
+ v_in[3+v_in_off] * m_in.get(3*4+i_m_in_off);
}
}
@@ -520,15 +1671,16 @@ public class FloatUtil {
* @param v_in 4-component column-vector
* @param v_out m_in * v_in
*/
- public static final void multMatrixVecf(FloatBuffer m_in, float[] v_in, float[] v_out) {
- final int matrixPos = m_in.position();
+ 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+matrixPos) +
- v_in[1] * m_in.get(1*4+i+matrixPos) +
- v_in[2] * m_in.get(2*4+i+matrixPos) +
- v_in[3] * m_in.get(3*4+i+matrixPos);
+ 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);
}
}
@@ -537,17 +1689,18 @@ public class FloatUtil {
* @param v_in 4-component column-vector
* @param v_out m_in * v_in
*/
- public static final void multMatrixVecf(FloatBuffer m_in, FloatBuffer v_in, FloatBuffer v_out) {
- final int inPos = v_in.position();
- final int outPos = v_out.position();
- final int matrixPos = m_in.position();
+ public static void multMatrixVec(final FloatBuffer m_in, final FloatBuffer v_in, final FloatBuffer v_out) {
+ final int v_in_off = v_in.position();
+ final int v_out_off = v_out.position();
+ 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)
- v_out.put(i + outPos,
- v_in.get(0+inPos) * m_in.get(0*4+i+matrixPos) +
- v_in.get(1+inPos) * m_in.get(1*4+i+matrixPos) +
- v_in.get(2+inPos) * m_in.get(2*4+i+matrixPos) +
- v_in.get(3+inPos) * m_in.get(3*4+i+matrixPos));
+ final int i_m_in_off = i+m_in_off;
+ v_out.put(i + v_out_off,
+ v_in.get(0+v_in_off) * m_in.get(0*4+i_m_in_off) +
+ v_in.get(1+v_in_off) * m_in.get(1*4+i_m_in_off) +
+ v_in.get(2+v_in_off) * m_in.get(2*4+i_m_in_off) +
+ v_in.get(3+v_in_off) * m_in.get(3*4+i_m_in_off));
}
}
@@ -562,7 +1715,7 @@ public class FloatUtil {
* @param v_out the column-vector storage, at least 3 components long
* @param v_out_off offset to storage
*/
- public static final void copyMatrixColumn(final float[] m_in, final int m_in_off, final int column, final float[] v_out, final int v_out_off) {
+ public static void copyMatrixColumn(final float[] m_in, final int m_in_off, final int column, final float[] v_out, final int v_out_off) {
v_out[0+v_out_off]=m_in[0+column*4+m_in_off];
v_out[1+v_out_off]=m_in[1+column*4+m_in_off];
v_out[2+v_out_off]=m_in[2+column*4+m_in_off];
@@ -582,7 +1735,7 @@ public class FloatUtil {
* @param v_out the row-vector storage, at least 3 components long
* @param v_out_off offset to storage
*/
- public static final void copyMatrixRow(final float[] m_in, final int m_in_off, final int row, final float[] v_out, final int v_out_off) {
+ public static void copyMatrixRow(final float[] m_in, final int m_in_off, final int row, final float[] v_out, final int v_out_off) {
v_out[0+v_out_off]=m_in[row+0*4+m_in_off];
v_out[1+v_out_off]=m_in[row+1*4+m_in_off];
v_out[2+v_out_off]=m_in[row+2*4+m_in_off];
@@ -602,7 +1755,9 @@ public class FloatUtil {
* @param row row number to print
* @return matrix row string representation
*/
- public static StringBuilder matrixRowToString(StringBuilder sb, String f, FloatBuffer a, int aOffset, int rows, int columns, boolean rowMajorOrder, int row) {
+ 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();
}
@@ -630,7 +1785,8 @@ public class FloatUtil {
* @param row row number to print
* @return matrix row string representation
*/
- public static StringBuilder matrixRowToString(StringBuilder sb, String f, float[] a, int aOffset, int rows, int columns, boolean rowMajorOrder, int row) {
+ 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();
}
@@ -657,7 +1813,8 @@ public class FloatUtil {
* @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, String rowPrefix, String f, FloatBuffer a, int aOffset, int rows, int columns, boolean rowMajorOrder) {
+ 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();
}
@@ -681,7 +1838,8 @@ public class FloatUtil {
* @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, String rowPrefix, String f, float[] a, int aOffset, int rows, int columns, boolean rowMajorOrder) {
+ 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();
}
@@ -707,7 +1865,9 @@ public class FloatUtil {
* @param rowMajorOrder if true floats are layed out in row-major-order, otherwise column-major-order (OpenGL)
* @return side by side representation
*/
- public static StringBuilder matrixToString(StringBuilder sb, String rowPrefix, String f, FloatBuffer a, int aOffset, FloatBuffer b, int bOffset, int rows, int columns, boolean rowMajorOrder) {
+ public static StringBuilder matrixToString(StringBuilder sb, final String rowPrefix, final String f,
+ final FloatBuffer a, final int aOffset, final FloatBuffer b, final int bOffset,
+ final int rows, final int columns, final boolean rowMajorOrder) {
if(null == sb) {
sb = new StringBuilder();
}
@@ -735,7 +1895,9 @@ public class FloatUtil {
* @param rowMajorOrder if true floats are layed out in row-major-order, otherwise column-major-order (OpenGL)
* @return side by side representation
*/
- public static StringBuilder matrixToString(StringBuilder sb, String rowPrefix, String f, float[] a, int aOffset, float[] b, int bOffset, int rows, int columns, boolean rowMajorOrder) {
+ public static StringBuilder matrixToString(StringBuilder sb, final String rowPrefix, final String f,
+ final float[] a, final int aOffset, final float[] b, final int bOffset,
+ final int rows, final int columns, final boolean rowMajorOrder) {
if(null == sb) {
sb = new StringBuilder();
}
@@ -750,6 +1912,10 @@ public class FloatUtil {
return sb;
}
+ //
+ // Scalar Ops
+ //
+
@SuppressWarnings("unused")
private static void calculateMachineEpsilonFloat() {
final long t0;
@@ -973,7 +2139,7 @@ public class FloatUtil {
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>.
diff --git a/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java b/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java
index 319cbad50..502da42c2 100644
--- a/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java
+++ b/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java
@@ -1038,8 +1038,7 @@ public class Quaternion {
final float norm = magnitudeSquared();
if ( FloatUtil.isZero(norm, FloatUtil.EPSILON) ) {
// identity matrix -> srecip = 0f
- FloatUtil.makeIdentityf(matrix, mat_offset);
- return matrix;
+ return FloatUtil.makeIdentity(matrix, mat_offset);
}
final float srecip;
if ( FloatUtil.isEqual(1f, norm, FloatUtil.EPSILON) ) {
@@ -1106,8 +1105,7 @@ public class Quaternion {
final float norm = magnitudeSquared();
if ( FloatUtil.isZero(norm, FloatUtil.EPSILON) ) {
// identity matrix -> srecip = 0f
- FloatUtil.makeIdentityf(matrix);
- return matrix;
+ return FloatUtil.makeIdentity(matrix);
}
final float srecip;
if ( FloatUtil.isEqual(1f, norm, FloatUtil.EPSILON) ) {
diff --git a/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java b/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java
index 7e4f45795..607d8ef9d 100644
--- a/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java
@@ -29,7 +29,7 @@ package com.jogamp.opengl.math;
import java.util.ArrayList;
-public class VectorUtil {
+public final class VectorUtil {
public static final float[] VEC3_ONE = { 1f, 1f, 1f };
public static final float[] VEC3_ZERO = { 0f, 0f, 0f };
@@ -248,11 +248,33 @@ public class VectorUtil {
/**
* Return the squared length of a vector, a.k.a the squared <i>norm</i> or squared <i>magnitude</i>
*/
+ public static float normSquareVec2(final float[] vec, final int offset) {
+ float v = vec[0+offset];
+ float r = v*v;
+ v = vec[1+offset];
+ return r + v*v;
+ }
+
+ /**
+ * Return the squared length of a vector, a.k.a the squared <i>norm</i> or squared <i>magnitude</i>
+ */
public static float normSquareVec3(final float[] vec) {
return vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2];
}
/**
+ * Return the squared length of a vector, a.k.a the squared <i>norm</i> or squared <i>magnitude</i>
+ */
+ public static float normSquareVec3(final float[] vec, final int offset) {
+ float v = vec[0+offset];
+ float r = v*v;
+ v = vec[1+offset];
+ r += v*v;
+ v = vec[2+offset];
+ return r + v*v;
+ }
+
+ /**
* Return the length of a vector, a.k.a the <i>norm</i> or <i>magnitude</i>
*/
public static float normVec2(final float[] vec) {
@@ -347,6 +369,26 @@ public class VectorUtil {
}
/**
+ * Normalize a vector in place
+ * @param vector input vector
+ * @return normalized output vector
+ */
+ public static float[] normalizeVec3(final float[] vector, final int offset) {
+ final float lengthSq = normSquareVec3(vector, offset);
+ if ( FloatUtil.isZero(lengthSq, FloatUtil.EPSILON) ) {
+ vector[0+offset] = 0f;
+ vector[1+offset] = 0f;
+ vector[2+offset] = 0f;
+ } else {
+ final float invSqr = 1f / FloatUtil.sqrt(lengthSq);
+ vector[0+offset] *= invSqr;
+ vector[1+offset] *= invSqr;
+ vector[2+offset] *= invSqr;
+ }
+ return vector;
+ }
+
+ /**
* Scales a vector by param using given result float[]
* @param result vector for the result, may be vector (in-place)
* @param vector input vector
@@ -471,6 +513,20 @@ public class VectorUtil {
}
/**
+ * cross product vec1 x vec2
+ * @param v1 vector 1
+ * @param v2 vector 2
+ * @return the resulting vector
+ */
+ public static float[] crossVec3(final float[] r, final int r_offset, final float[] v1, final int v1_offset, final float[] v2, final int v2_offset)
+ {
+ r[0+r_offset] = v1[1+v1_offset] * v2[2+v2_offset] - v1[2+v1_offset] * v2[1+v2_offset];
+ r[1+r_offset] = v1[2+v1_offset] * v2[0+v2_offset] - v1[0+v1_offset] * v2[2+v2_offset];
+ r[2+r_offset] = v1[0+v1_offset] * v2[1+v2_offset] - v1[1+v1_offset] * v2[0+v2_offset];
+ return r;
+ }
+
+ /**
* Multiplication of column-major 4x4 matrix with vector
* @param colMatrix column matrix (4x4)
* @param vec vector(x,y,z)
diff --git a/src/jogl/classes/com/jogamp/opengl/math/geom/AABBox.java b/src/jogl/classes/com/jogamp/opengl/math/geom/AABBox.java
index e4c1445ff..d87bbb6f9 100644
--- a/src/jogl/classes/com/jogamp/opengl/math/geom/AABBox.java
+++ b/src/jogl/classes/com/jogamp/opengl/math/geom/AABBox.java
@@ -33,7 +33,6 @@ import com.jogamp.opengl.math.FloatUtil;
import com.jogamp.opengl.math.Quaternion;
import com.jogamp.opengl.math.Ray;
import com.jogamp.opengl.math.VectorUtil;
-import com.jogamp.opengl.util.PMVMatrix;
/**
@@ -680,9 +679,9 @@ public class AABBox {
* compute the window bounding box.
* <p>
* If <code>useCenterZ</code> is <code>true</code>,
- * only 4 {@link PMVMatrix#gluProject(float, float, float, int[], int, float[], int) gluProject}
+ * only 4 {@link FloatUtil#mapObjToWinCoords(float, float, float, float[], int[], int, float[], int, float[], float[]) mapObjToWinCoords}
* operations are made on points [1..4] using {@link #getCenter()}'s z-value.
- * Otherwise 8 {@link PMVMatrix#gluProject(float, float, float, int[], int, float[], int) gluProject}
+ * Otherwise 8 {@link FloatUtil#mapObjToWinCoords(float, float, float, float[], int[], int, float[], int, float[], float[]) mapObjToWinCoords}
* operation on all 8 points are performed.
* </p>
* <pre>
@@ -691,39 +690,53 @@ public class AABBox {
* | |
* [1] ------ [3]
* </pre>
- * @param pmv
+ * @param mat4PMv P x Mv matrix
* @param view
* @param useCenterZ
- * @param tmpV3 TODO
+ * @param vec3Tmp0 3 component vector for temp storage
+ * @param vec4Tmp1 4 component vector for temp storage
+ * @param vec4Tmp2 4 component vector for temp storage
* @return
*/
- public AABBox mapToWindow(final AABBox result, final PMVMatrix pmv, final int[] view, final boolean useCenterZ, float[] tmpV3) {
- // System.err.printf("AABBox.mapToWindow.0: view[%d, %d, %d, %d], this %s%n", view[0], view[1], view[2], view[3], toString());
- float objZ = useCenterZ ? center[2] : getMinZ();
- pmv.gluProject(getMinX(), getMinY(), objZ, view, 0, tmpV3, 0);
- // System.err.printf("AABBox.mapToWindow.p1: %f, %f, %f -> %f, %f, %f%n", getMinX(), getMinY(), objZ, tmpV3[0], tmpV3[1], tmpV3[2]);
- // System.err.printf("AABBox.mapToWindow.p1: %s%n", pmv.toString());
- result.reset();
- result.resize(tmpV3, 0);
- pmv.gluProject(getMinX(), getMaxY(), objZ, view, 0, tmpV3, 0);
- // System.err.printf("AABBox.mapToWindow.p2: %f, %f, %f -> %f, %f, %f%n", getMinX(), getMaxY(), objZ, tmpV3[0], tmpV3[1], tmpV3[2]);
- result.resize(tmpV3, 0);
- pmv.gluProject(getMaxX(), getMinY(), objZ, view, 0, tmpV3, 0);
- // System.err.printf("AABBox.mapToWindow.p3: %f, %f, %f -> %f, %f, %f%n", getMaxX(), getMinY(), objZ, tmpV3[0], tmpV3[1], tmpV3[2]);
- result.resize(tmpV3, 0);
- pmv.gluProject(getMaxX(), getMaxY(), objZ, view, 0, tmpV3, 0);
- // System.err.printf("AABBox.mapToWindow.p4: %f, %f, %f -> %f, %f, %f%n", getMaxX(), getMaxY(), objZ, tmpV3[0], tmpV3[1], tmpV3[2]);
- result.resize(tmpV3, 0);
+ public AABBox mapToWindow(final AABBox result, final float[/*16*/] mat4PMv, final int[] view, final boolean useCenterZ,
+ final float[] vec3Tmp0, final float[] vec4Tmp1, final float[] vec4Tmp2) {
+ {
+ // System.err.printf("AABBox.mapToWindow.0: view[%d, %d, %d, %d], this %s%n", view[0], view[1], view[2], view[3], toString());
+ final float objZ = useCenterZ ? center[2] : getMinZ();
+ FloatUtil.mapObjToWinCoords(getMinX(), getMinY(), objZ, mat4PMv, view, 0, vec3Tmp0, 0, vec4Tmp1, vec4Tmp2);
+ // System.err.printf("AABBox.mapToWindow.p1: %f, %f, %f -> %f, %f, %f%n", getMinX(), getMinY(), objZ, vec3Tmp0[0], vec3Tmp0[1], vec3Tmp0[2]);
+ // System.err.println("AABBox.mapToWindow.p1:");
+ // System.err.println(FloatUtil.matrixToString(null, " mat4PMv", "%10.5f", mat4PMv, 0, 4, 4, false /* rowMajorOrder */));
+
+ result.reset();
+ result.resize(vec3Tmp0, 0);
+
+ FloatUtil.mapObjToWinCoords(getMinX(), getMaxY(), objZ, mat4PMv, view, 0, vec3Tmp0, 0, vec4Tmp1, vec4Tmp2);
+ // System.err.printf("AABBox.mapToWindow.p2: %f, %f, %f -> %f, %f, %f%n", getMinX(), getMaxY(), objZ, vec3Tmp0[0], vec3Tmp0[1], vec3Tmp0[2]);
+ result.resize(vec3Tmp0, 0);
+
+ FloatUtil.mapObjToWinCoords(getMaxX(), getMinY(), objZ, mat4PMv, view, 0, vec3Tmp0, 0, vec4Tmp1, vec4Tmp2);
+ // System.err.printf("AABBox.mapToWindow.p3: %f, %f, %f -> %f, %f, %f%n", getMaxX(), getMinY(), objZ, vec3Tmp0[0], vec3Tmp0[1], vec3Tmp0[2]);
+ result.resize(vec3Tmp0, 0);
+
+ FloatUtil.mapObjToWinCoords(getMaxX(), getMaxY(), objZ, mat4PMv, view, 0, vec3Tmp0, 0, vec4Tmp1, vec4Tmp2);
+ // System.err.printf("AABBox.mapToWindow.p4: %f, %f, %f -> %f, %f, %f%n", getMaxX(), getMaxY(), objZ, vec3Tmp0[0], vec3Tmp0[1], vec3Tmp0[2]);
+ result.resize(vec3Tmp0, 0);
+ }
+
if( !useCenterZ ) {
- objZ = getMaxZ();
- pmv.gluProject(getMinX(), getMinY(), objZ, view, 0, tmpV3, 0);
- result.resize(tmpV3, 0);
- pmv.gluProject(getMinX(), getMaxY(), objZ, view, 0, tmpV3, 0);
- result.resize(tmpV3, 0);
- pmv.gluProject(getMaxX(), getMinY(), objZ, view, 0, tmpV3, 0);
- result.resize(tmpV3, 0);
- pmv.gluProject(getMaxX(), getMaxY(), objZ, view, 0, tmpV3, 0);
- result.resize(tmpV3, 0);
+ final float objZ = getMaxZ();
+ FloatUtil.mapObjToWinCoords(getMinX(), getMinY(), objZ, mat4PMv, view, 0, vec3Tmp0, 0, vec4Tmp1, vec4Tmp2);
+ result.resize(vec3Tmp0, 0);
+
+ FloatUtil.mapObjToWinCoords(getMinX(), getMaxY(), objZ, mat4PMv, view, 0, vec3Tmp0, 0, vec4Tmp1, vec4Tmp2);
+ result.resize(vec3Tmp0, 0);
+
+ FloatUtil.mapObjToWinCoords(getMaxX(), getMinY(), objZ, mat4PMv, view, 0, vec3Tmp0, 0, vec4Tmp1, vec4Tmp2);
+ result.resize(vec3Tmp0, 0);
+
+ FloatUtil.mapObjToWinCoords(getMaxX(), getMaxY(), objZ, mat4PMv, view, 0, vec3Tmp0, 0, vec4Tmp1, vec4Tmp2);
+ result.resize(vec3Tmp0, 0);
}
if( DEBUG ) {
System.err.printf("AABBox.mapToWindow: view[%d, %d], this %s -> %s%n", view[0], view[1], toString(), result.toString());
diff --git a/src/jogl/classes/com/jogamp/opengl/math/geom/Frustum.java b/src/jogl/classes/com/jogamp/opengl/math/geom/Frustum.java
index 8b4eba222..87d31becb 100644
--- a/src/jogl/classes/com/jogamp/opengl/math/geom/Frustum.java
+++ b/src/jogl/classes/com/jogamp/opengl/math/geom/Frustum.java
@@ -68,7 +68,7 @@ import com.jogamp.common.os.Platform;
*/
public class Frustum {
/** Normalized planes[l, r, b, t, n, f] */
- protected Plane[] planes = new Plane[6];
+ protected final Plane[] planes = new Plane[6];
/**
* Creates an undefined instance w/o calculating the frustum.
diff --git a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
index c6f1f529d..f79efad2f 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
@@ -34,7 +34,6 @@
package com.jogamp.opengl.util;
-import java.nio.Buffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
@@ -42,15 +41,12 @@ import javax.media.opengl.GL;
import javax.media.opengl.GLException;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
-import jogamp.opengl.ProjectFloat;
-
import com.jogamp.common.nio.Buffers;
import com.jogamp.common.os.Platform;
import com.jogamp.common.util.FloatStack;
import com.jogamp.opengl.math.FloatUtil;
import com.jogamp.opengl.math.Quaternion;
import com.jogamp.opengl.math.Ray;
-import com.jogamp.opengl.math.VectorUtil;
import com.jogamp.opengl.math.geom.AABBox;
import com.jogamp.opengl.math.geom.Frustum;
@@ -77,30 +73,28 @@ import com.jogamp.opengl.math.geom.Frustum;
* </p>
* <a name="storageDetails"><h5>Matrix storage details</h5></a>
* <p>
- * All matrices use a common FloatBuffer storage
- * and are a {@link Buffers#slice2Float(Buffer, float[], int, int) sliced} representation of it.
- * The common FloatBuffer and hence all matrices may use NIO direct storage or a {@link #usesBackingArray() backing float array},
- * depending how the instance if {@link #PMVMatrix(boolean) being constructed}.
+ * All matrices are backed up by a common primitive float-array for performance considerations
+ * and are a {@link Buffers#slice2Float(float[], int, int) sliced} representation of it.
* </p>
* <p>
* <b>Note:</b>
* <ul>
- * <li>The matrix is a {@link Buffers#slice2Float(Buffer, float[], int, int) sliced part } of a host matrix and it's start position has been {@link FloatBuffer#mark() marked}.</li>
+ * <li>The matrix is a {@link Buffers#slice2Float(float[], int, int) sliced part } of a host matrix and it's start position has been {@link FloatBuffer#mark() marked}.</li>
* <li>Use {@link FloatBuffer#reset() reset()} to rewind it to it's start position after relative operations, like {@link FloatBuffer#get() get()}.</li>
* <li>If using absolute operations like {@link FloatBuffer#get(int) get(int)}, use it's {@link FloatBuffer#reset() reset} {@link FloatBuffer#position() position} as it's offset.</li>
* </ul>
* </p>
*/
-public class PMVMatrix implements GLMatrixFunc {
+public final class PMVMatrix implements GLMatrixFunc {
/** Bit value stating a modified {@link #glGetPMatrixf() projection matrix (P)}, since last {@link #update()} call. */
- public static final int MODIFIED_PROJECTION = 1 << 0;
+ public static final int MODIFIED_PROJECTION = 1 << 0;
/** Bit value stating a modified {@link #glGetMvMatrixf() modelview matrix (Mv)}, since last {@link #update()} call. */
- public static final int MODIFIED_MODELVIEW = 1 << 1;
+ public static final int MODIFIED_MODELVIEW = 1 << 1;
/** Bit value stating a modified {@link #glGetTMatrixf() texture matrix (T)}, since last {@link #update()} call. */
- public static final int MODIFIED_TEXTURE = 1 << 2;
+ public static final int MODIFIED_TEXTURE = 1 << 2;
/** Bit value stating all is modified */
- public static final int MODIFIED_ALL = MODIFIED_PROJECTION | MODIFIED_MODELVIEW | MODIFIED_TEXTURE ;
+ public static final int MODIFIED_ALL = MODIFIED_PROJECTION | MODIFIED_MODELVIEW | MODIFIED_TEXTURE ;
/** Bit value stating a dirty {@link #glGetMviMatrixf() inverse modelview matrix (Mvi)}. */
public static final int DIRTY_INVERSE_MODELVIEW = 1 << 0;
@@ -196,97 +190,65 @@ public class PMVMatrix implements GLMatrixFunc {
}
/**
- * Creates an instance of PMVMatrix {@link #PMVMatrix(boolean) PMVMatrix(boolean useBackingArray)},
- * with <code>useBackingArray = true</code>.
- */
- public PMVMatrix() {
- this(true);
- }
-
- /**
* Creates an instance of PMVMatrix.
- *
- * @param useBackingArray <code>true</code> for non direct NIO Buffers with guaranteed backing array,
- * which allows faster access in Java computation.
- * <p><code>false</code> for direct NIO buffers w/o a guaranteed backing array.
- * In most Java implementations, direct NIO buffers have no backing array
- * and hence the Java computation will be throttled down by direct IO get/put
- * operations.</p>
- * <p>Depending on the application, ie. whether the Java computation or
- * JNI invocation and hence native data transfer part is heavier,
- * this flag shall be set to <code>true</code> or <code>false</code></p>.
+ * <p>
+ * Implementation uses non-direct non-NIO Buffers with guaranteed backing array,
+ * which allows faster access in Java computation.
+ * </p>
*/
- public PMVMatrix(boolean useBackingArray) {
- this.usesBackingArray = useBackingArray;
-
+ public PMVMatrix() {
// I Identity
// T Texture
// P Projection
// Mv ModelView
// Mvi Modelview-Inverse
// Mvit Modelview-Inverse-Transpose
- if(useBackingArray) {
- matrixBufferArray = new float[ 6*16 + ProjectFloat.getRequiredFloatBufferSize() ];
- matrixBuffer = null;
- } else {
- matrixBufferArray = null;
- matrixBuffer = Buffers.newDirectByteBuffer( ( 6*16 + ProjectFloat.getRequiredFloatBufferSize() ) * Buffers.SIZEOF_FLOAT );
- matrixBuffer.mark();
- }
-
- matrixIdent = Buffers.slice2Float(matrixBuffer, matrixBufferArray, 0*16, 1*16); // I
- matrixTex = Buffers.slice2Float(matrixBuffer, matrixBufferArray, 1*16, 1*16); // T
- matrixPMvMvit = Buffers.slice2Float(matrixBuffer, matrixBufferArray, 2*16, 4*16); // P + Mv + Mvi + Mvit
- matrixPMvMvi = Buffers.slice2Float(matrixBuffer, matrixBufferArray, 2*16, 3*16); // P + Mv + Mvi
- matrixPMv = Buffers.slice2Float(matrixBuffer, matrixBufferArray, 2*16, 2*16); // P + Mv
- matrixP = Buffers.slice2Float(matrixBuffer, matrixBufferArray, 2*16, 1*16); // P
- matrixMv = Buffers.slice2Float(matrixBuffer, matrixBufferArray, 3*16, 1*16); // Mv
- matrixMvi = Buffers.slice2Float(matrixBuffer, matrixBufferArray, 4*16, 1*16); // Mvi
- matrixMvit = Buffers.slice2Float(matrixBuffer, matrixBufferArray, 5*16, 1*16); // Mvit
-
- projectFloat = new ProjectFloat(matrixBuffer, matrixBufferArray, 6*16);
-
- if(null != matrixBuffer) {
- matrixBuffer.reset();
- }
- FloatUtil.makeIdentityf(matrixIdent);
-
- tmpVec3f = new float[3];
- tmpMatrix = new float[16];
- matrixRot = new float[16];
- matrixMult = new float[16];
- matrixTrans = new float[16];
- matrixScale = new float[16];
- matrixOrtho = new float[16];
- matrixFrustum = new float[16];
- FloatUtil.makeIdentityf(matrixTrans, 0);
- FloatUtil.makeIdentityf(matrixRot, 0);
- FloatUtil.makeIdentityf(matrixScale, 0);
- FloatUtil.makeIdentityf(matrixOrtho, 0);
- FloatUtil.makeZero(matrixFrustum, 0);
+ matrixArray = new float[5*16];
+
+ mP_offset = 0*16;
+ mMv_offset = 1*16;
+ mTex_offset = 4*16;
+
+ matrixPMvMvit = Buffers.slice2Float(matrixArray, 0*16, 4*16); // P + Mv + Mvi + Mvit
+ matrixPMvMvi = Buffers.slice2Float(matrixArray, 0*16, 3*16); // P + Mv + Mvi
+ matrixPMv = Buffers.slice2Float(matrixArray, 0*16, 2*16); // P + Mv
+ matrixP = Buffers.slice2Float(matrixArray, 0*16, 1*16); // P
+ matrixMv = Buffers.slice2Float(matrixArray, 1*16, 1*16); // Mv
+ matrixMvi = Buffers.slice2Float(matrixArray, 2*16, 1*16); // Mvi
+ matrixMvit = Buffers.slice2Float(matrixArray, 3*16, 1*16); // Mvit
+ matrixTex = Buffers.slice2Float(matrixArray, 4*16, 1*16); // T
+
+ mat4Tmp1 = new float[16];
+ mat4Tmp2 = new float[16];
+ mat4Tmp3 = new float[16];
+ matrixTxSx = new float[16];
+ FloatUtil.makeIdentity(matrixTxSx);
// Start w/ zero size to save memory
matrixTStack = new FloatStack( 0, 2*16); // growSize: GL-min size (2)
matrixPStack = new FloatStack( 0, 2*16); // growSize: GL-min size (2)
matrixMvStack= new FloatStack( 0, 16*16); // growSize: half GL-min size (32)
- // default values and mode
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glMatrixMode(GL.GL_TEXTURE);
- glLoadIdentity();
- modifiedBits = MODIFIED_ALL;
- dirtyBits = DIRTY_ALL;
- requestMask = 0;
- matrixMode = GL_MODELVIEW;
+ reset();
frustum = null;
}
- /** @see #PMVMatrix(boolean) */
- public final boolean usesBackingArray() { return usesBackingArray; }
+ /**
+ * Issues {@link #glLoadIdentity()} on all matrices,
+ * i.e. {@link GLMatrixFunc#GL_MODELVIEW GL_MODELVIEW}, {@link GLMatrixFunc#GL_PROJECTION GL_PROJECTION} or {@link GL#GL_TEXTURE GL_TEXTURE}
+ * and resets all internal states.
+ */
+ public final void reset() {
+ FloatUtil.makeIdentity(matrixArray, mMv_offset);
+ FloatUtil.makeIdentity(matrixArray, mP_offset);
+ FloatUtil.makeIdentity(matrixArray, mTex_offset);
+
+ modifiedBits = MODIFIED_ALL;
+ dirtyBits = DIRTY_ALL;
+ requestMask = 0;
+ matrixMode = GL_MODELVIEW;
+ }
/** Returns the current matrix-mode, one of {@link GLMatrixFunc#GL_MODELVIEW GL_MODELVIEW}, {@link GLMatrixFunc#GL_PROJECTION GL_PROJECTION} or {@link GL#GL_TEXTURE GL_TEXTURE}. */
public final int glGetMatrixMode() {
@@ -402,7 +364,7 @@ public class PMVMatrix implements GLMatrixFunc {
}
/** Returns the frustum, derived from projection * modelview */
- public Frustum glGetFrustum() {
+ public final Frustum glGetFrustum() {
requestMask |= DIRTY_FRUSTUM;
updateImpl(false);
return frustum;
@@ -420,7 +382,7 @@ public class PMVMatrix implements GLMatrixFunc {
* {@link GLMatrixFunc#GL_MODELVIEW_MATRIX GL_MODELVIEW_MATRIX}, {@link GLMatrixFunc#GL_PROJECTION_MATRIX GL_PROJECTION_MATRIX} or {@link GLMatrixFunc#GL_TEXTURE_MATRIX GL_TEXTURE_MATRIX},
* or a matrix-mode-name, i.e.
* {@link GLMatrixFunc#GL_MODELVIEW GL_MODELVIEW}, {@link GLMatrixFunc#GL_PROJECTION GL_PROJECTION} or {@link GL#GL_TEXTURE GL_TEXTURE}
- * @return the named matrix
+ * @return the named matrix, not a copy!
*/
public final FloatBuffer glGetMatrixf(final int matrixName) {
switch(matrixName) {
@@ -438,6 +400,35 @@ public class PMVMatrix implements GLMatrixFunc {
}
}
+
+ /**
+ * Multiplies the {@link #glGetPMatrixf() P} and {@link #glGetMvMatrixf() Mv} matrix, i.e.
+ * <pre>
+ * mat4PMv = P x Mv
+ * </pre>
+ * @param mat4PMv 4x4 matrix storage for result
+ * @param mat4PMv_offset
+ * @return given matrix for chaining
+ */
+ public final float[] multPMvMatrixf(final float[/*16*/] mat4PMv, final int mat4PMv_offset) {
+ FloatUtil.multMatrix(matrixArray, mP_offset, matrixArray, mMv_offset, mat4PMv, mat4PMv_offset);
+ return mat4PMv;
+ }
+
+ /**
+ * Multiplies the {@link #glGetMvMatrixf() Mv} and {@link #glGetPMatrixf() P} matrix, i.e.
+ * <pre>
+ * mat4MvP = Mv x P
+ * </pre>
+ * @param mat4MvP 4x4 matrix storage for result
+ * @param mat4MvP_offset
+ * @return given matrix for chaining
+ */
+ public final float[] multMvPMatrixf(final float[/*16*/] mat4MvP, final int mat4MvP_offset) {
+ FloatUtil.multMatrix(matrixArray, mMv_offset, matrixArray, mP_offset, mat4MvP, mat4MvP_offset);
+ return mat4MvP;
+ }
+
//
// GLMatrixFunc implementation
//
@@ -593,35 +584,31 @@ public class PMVMatrix implements GLMatrixFunc {
@Override
public final void glLoadIdentity() {
if(matrixMode==GL_MODELVIEW) {
- matrixMv.put(matrixIdent);
- matrixMv.reset();
+ FloatUtil.makeIdentity(matrixArray, mMv_offset);
dirtyBits |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW | DIRTY_FRUSTUM ;
modifiedBits |= MODIFIED_MODELVIEW;
} else if(matrixMode==GL_PROJECTION) {
- matrixP.put(matrixIdent);
- matrixP.reset();
+ FloatUtil.makeIdentity(matrixArray, mP_offset);
dirtyBits |= DIRTY_FRUSTUM ;
modifiedBits |= MODIFIED_PROJECTION;
} else if(matrixMode==GL.GL_TEXTURE) {
- matrixTex.put(matrixIdent);
- matrixTex.reset();
+ FloatUtil.makeIdentity(matrixArray, mTex_offset);
modifiedBits |= MODIFIED_TEXTURE;
}
- matrixIdent.reset();
}
@Override
public final void glMultMatrixf(final FloatBuffer m) {
if(matrixMode==GL_MODELVIEW) {
- FloatUtil.multMatrixf(matrixMv, m);
+ FloatUtil.multMatrix(matrixMv, m);
dirtyBits |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW | DIRTY_FRUSTUM ;
modifiedBits |= MODIFIED_MODELVIEW;
} else if(matrixMode==GL_PROJECTION) {
- FloatUtil.multMatrixf(matrixP, m);
+ FloatUtil.multMatrix(matrixP, m);
dirtyBits |= DIRTY_FRUSTUM ;
modifiedBits |= MODIFIED_PROJECTION;
} else if(matrixMode==GL.GL_TEXTURE) {
- FloatUtil.multMatrixf(matrixTex, m);
+ FloatUtil.multMatrix(matrixTex, m);
modifiedBits |= MODIFIED_TEXTURE;
}
}
@@ -629,69 +616,49 @@ public class PMVMatrix implements GLMatrixFunc {
@Override
public final void glMultMatrixf(final float[] m, final int m_offset) {
if(matrixMode==GL_MODELVIEW) {
- FloatUtil.multMatrixf(matrixMv, m, m_offset);
+ FloatUtil.multMatrix(matrixArray, mMv_offset, m, m_offset);
dirtyBits |= DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW | DIRTY_FRUSTUM ;
modifiedBits |= MODIFIED_MODELVIEW;
} else if(matrixMode==GL_PROJECTION) {
- FloatUtil.multMatrixf(matrixP, m, m_offset);
+ FloatUtil.multMatrix(matrixArray, mP_offset, m, m_offset);
dirtyBits |= DIRTY_FRUSTUM ;
modifiedBits |= MODIFIED_PROJECTION;
} else if(matrixMode==GL.GL_TEXTURE) {
- FloatUtil.multMatrixf(matrixTex, m, m_offset);
+ FloatUtil.multMatrix(matrixArray, mTex_offset, m, m_offset);
modifiedBits |= MODIFIED_TEXTURE;
}
}
@Override
public final void glTranslatef(final float x, final float y, final float z) {
- // Translation matrix (Column Order):
- // 1 0 0 0
- // 0 1 0 0
- // 0 0 1 0
- // x y z 1
- matrixTrans[0+4*3] = x;
- matrixTrans[1+4*3] = y;
- matrixTrans[2+4*3] = z;
- glMultMatrixf(matrixTrans, 0);
+ glMultMatrixf(FloatUtil.makeTranslation(matrixTxSx, false, x, y, z), 0);
+ }
+
+ @Override
+ public final void glScalef(final float x, final float y, final float z) {
+ glMultMatrixf(FloatUtil.makeScale(matrixTxSx, false, x, y, z), 0);
}
@Override
public final void glRotatef(final float angdeg, final float x, final float y, final float z) {
- final float angrad = angdeg * FloatUtil.PI / 180.0f;
- FloatUtil.makeRotationAxis(angrad, x, y, z, matrixRot, 0, tmpVec3f);
- glMultMatrixf(matrixRot, 0);
+ glMultMatrixf(FloatUtil.makeRotationAxis(mat4Tmp1, 0, angdeg * FloatUtil.PI / 180.0f, x, y, z, mat4Tmp2), 0);
}
/**
* Rotate the current matrix with the given {@link Quaternion}'s rotation {@link Quaternion#toMatrix(float[], int) matrix representation}.
*/
public final void glRotate(final Quaternion quat) {
- quat.toMatrix(tmpMatrix, 0);
- glMultMatrixf(tmpMatrix, 0);
- }
-
- @Override
- public final void glScalef(final float x, final float y, final float z) {
- // Scale matrix (Any Order):
- // x 0 0 0
- // 0 y 0 0
- // 0 0 z 0
- // 0 0 0 1
- matrixScale[0+4*0] = x;
- matrixScale[1+4*1] = y;
- matrixScale[2+4*2] = z;
-
- glMultMatrixf(matrixScale, 0);
+ glMultMatrixf(quat.toMatrix(mat4Tmp1, 0), 0);
}
@Override
public final void glOrthof(final float left, final float right, final float bottom, final float top, final float zNear, final float zFar) {
- glMultMatrixf( FloatUtil.makeOrthof(matrixOrtho, 0, false, left, right, bottom, top, zNear, zFar), 0 );
+ glMultMatrixf( FloatUtil.makeOrtho(mat4Tmp1, 0, true, left, right, bottom, top, zNear, zFar), 0 );
}
@Override
public final void glFrustumf(final float left, final float right, final float bottom, final float top, final float zNear, final float zFar) {
- glMultMatrixf( FloatUtil.makeFrustumf(matrixFrustum, 0, false, left, right, bottom, top, zNear, zFar), 0 );
+ glMultMatrixf( FloatUtil.makeFrustum(mat4Tmp1, 0, true, left, right, bottom, top, zNear, zFar), 0 );
}
//
@@ -702,7 +669,7 @@ public class PMVMatrix implements GLMatrixFunc {
* {@link #glMultMatrixf(FloatBuffer) Multiply} the {@link #glGetMatrixMode() current matrix} with the perspective/frustum matrix.
*/
public final void gluPerspective(final float fovy, final float aspect, final float zNear, final float zFar) {
- glMultMatrixf( FloatUtil.makePerspective(matrixFrustum, 0, false, fovy*((float)Math.PI)/360.0f, aspect, zNear, zFar), 0 );
+ glMultMatrixf( FloatUtil.makePerspective(mat4Tmp1, 0, true, fovy*((float)Math.PI)/360.0f, aspect, zNear, zFar), 0 );
}
/**
@@ -712,73 +679,124 @@ public class PMVMatrix implements GLMatrixFunc {
public final void gluLookAt(final float eyex, final float eyey, final float eyez,
final float centerx, final float centery, final float centerz,
final float upx, final float upy, final float upz) {
- projectFloat.gluLookAt(this, eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz);
+ mat4Tmp2[0+0] = eyex;
+ mat4Tmp2[1+0] = eyey;
+ mat4Tmp2[2+0] = eyez;
+ mat4Tmp2[0+4] = centerx;
+ mat4Tmp2[1+4] = centery;
+ mat4Tmp2[2+4] = centerz;
+ mat4Tmp2[0+8] = upx;
+ mat4Tmp2[1+8] = upy;
+ mat4Tmp2[2+8] = upz;
+ glMultMatrixf(
+ FloatUtil.makeLookAt(mat4Tmp1, 0, mat4Tmp2 /* eye */, 0, mat4Tmp2 /* center */, 4, mat4Tmp2 /* up */, 8, mat4Tmp3), 0);
}
/**
* Map object coordinates to window coordinates.
+ * <p>
+ * Traditional <code>gluProject</code> implementation.
+ * </p>
*
* @param objx
* @param objy
* @param objz
- * @param viewport
+ * @param viewport 4 component viewport vector
* @param viewport_offset
- * @param win_pos
+ * @param win_pos 3 component window coordinate, the result
* @param win_pos_offset
- * @return
+ * @return true if successful, otherwise false (z is 1)
*/
public final boolean gluProject(final float objx, final float objy, final float objz,
final int[] viewport, final int viewport_offset,
final float[] win_pos, final int win_pos_offset ) {
- if(usesBackingArray) {
- return projectFloat.gluProject(objx, objy, objz,
- matrixMv.array(), matrixMv.position(),
- matrixP.array(), matrixP.position(),
- viewport, viewport_offset,
- win_pos, win_pos_offset);
- } else {
- return projectFloat.gluProject(objx, objy, objz,
- matrixMv,
- matrixP,
- viewport, viewport_offset,
- win_pos, win_pos_offset);
- }
+ return FloatUtil.mapObjToWinCoords(objx, objy, objz,
+ matrixArray, mMv_offset,
+ matrixArray, mP_offset,
+ viewport, viewport_offset,
+ win_pos, win_pos_offset,
+ mat4Tmp1, mat4Tmp2);
}
/**
* Map window coordinates to object coordinates.
+ * <p>
+ * Traditional <code>gluUnProject</code> implementation.
+ * </p>
*
* @param winx
* @param winy
* @param winz
- * @param viewport
+ * @param viewport 4 component viewport vector
* @param viewport_offset
- * @param obj_pos
+ * @param obj_pos 3 component object coordinate, the result
* @param obj_pos_offset
- * @return true if successful, otherwise false (failed to invert matrix, or becomes z is infinity)
+ * @return true if successful, otherwise false (failed to invert matrix, or becomes infinity due to zero z)
*/
public final boolean gluUnProject(final float winx, final float winy, final float winz,
final int[] viewport, final int viewport_offset,
final float[] obj_pos, final int obj_pos_offset) {
- if(usesBackingArray) {
- return projectFloat.gluUnProject(winx, winy, winz,
- matrixMv.array(), matrixMv.position(),
- matrixP.array(), matrixP.position(),
- viewport, viewport_offset,
- obj_pos, obj_pos_offset);
- } else {
- return projectFloat.gluUnProject(winx, winy, winz,
- matrixMv,
- matrixP,
- viewport, viewport_offset,
- obj_pos, obj_pos_offset);
- }
+ return FloatUtil.mapWinToObjCoords(winx, winy, winz,
+ matrixArray, mMv_offset,
+ matrixArray, mP_offset,
+ viewport, viewport_offset,
+ obj_pos, obj_pos_offset,
+ mat4Tmp1, mat4Tmp2);
+ }
+
+ /**
+ * 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
+ * @return true if successful, otherwise false (failed to invert matrix, or becomes infinity due to zero z)
+ */
+ public boolean gluUnProject4(final float winx, final float winy, final float winz, final float clipw,
+ final int[] viewport, final int viewport_offset,
+ final float near, final float far,
+ final float[] obj_pos, final int obj_pos_offset ) {
+ return FloatUtil.mapWinToObjCoords(winx, winy, winz, clipw,
+ matrixArray, mMv_offset,
+ matrixArray, mP_offset,
+ viewport, viewport_offset,
+ near, far,
+ obj_pos, obj_pos_offset,
+ mat4Tmp1, mat4Tmp2);
}
+ /**
+ * Make given matrix the <i>pick</i> matrix based on given parameters.
+ * <p>
+ * Traditional <code>gluPickMatrix</code> implementation.
+ * </p>
+ * @param x
+ * @param y
+ * @param deltaX
+ * @param deltaY
+ * @param viewport 4 component viewport vector
+ * @param viewport_offset
+ */
public final void gluPickMatrix(final float x, final float y,
final float deltaX, final float deltaY,
final int[] viewport, final int viewport_offset) {
- projectFloat.gluPickMatrix(this, x, y, deltaX, deltaY, viewport, viewport_offset);
+ if( null != FloatUtil.makePick(mat4Tmp1, 0, x, y, deltaX, deltaY, viewport, viewport_offset, mat4Tmp2) ) {
+ glMultMatrixf(mat4Tmp1, 0);
+ }
}
/**
@@ -805,13 +823,12 @@ public class PMVMatrix implements GLMatrixFunc {
public final boolean gluUnProjectRay(final float winx, final float winy, final float winz0, final float winz1,
final int[] viewport, final int viewport_offset,
final Ray ray) {
- if( gluUnProject(winx, winy, winz0, viewport, viewport_offset, ray.orig, 0) &&
- gluUnProject(winx, winy, winz1, viewport, viewport_offset, ray.dir, 0) ) {
- VectorUtil.normalizeVec3( VectorUtil.subVec3(ray.dir, ray.dir, ray.orig) );
- return true;
- } else {
- return false;
- }
+ return FloatUtil.mapWinToRay(winx, winy, winz0, winz1,
+ matrixArray, mMv_offset,
+ matrixArray, mP_offset,
+ viewport, viewport_offset,
+ ray,
+ mat4Tmp1, mat4Tmp2, mat4Tmp3);
}
public StringBuilder toString(StringBuilder sb, String f) {
@@ -828,10 +845,9 @@ public class PMVMatrix implements GLMatrixFunc {
final boolean modMv = 0 != ( MODIFIED_MODELVIEW & modifiedBits );
final boolean modT = 0 != ( MODIFIED_TEXTURE & modifiedBits );
- sb.append("PMVMatrix[backingArray ").append(this.usesBackingArray());
- sb.append(", modified[P ").append(modP).append(", Mv ").append(modMv).append(", T ").append(modT);
- sb.append("], dirty/req[Mvi ").append(mviDirty).append("/").append(mviReq).append(", Mvit ").append(mvitDirty).append("/").append(mvitReq).append(", Frustum ").append(frustumDirty).append("/").append(frustumReq);
- sb.append("], Projection").append(Platform.NEWLINE);
+ sb.append("PMVMatrix[modified[P ").append(modP).append(", Mv ").append(modMv).append(", T ").append(modT);
+ sb.append("], dirty/req[Mvi ").append(mviDirty).append("/").append(mviReq).append(", Mvit ").append(mvitDirty).append("/").append(mvitReq).append(", Frustum ").append(frustumDirty).append("/").append(frustumReq).append("]").append(Platform.NEWLINE);
+ sb.append(", Projection").append(Platform.NEWLINE);
matrixToString(sb, f, matrixP);
sb.append(", Modelview").append(Platform.NEWLINE);
matrixToString(sb, f, matrixMv);
@@ -993,8 +1009,9 @@ public class PMVMatrix implements GLMatrixFunc {
if( null == frustum ) {
frustum = new Frustum();
}
- FloatUtil.multMatrixf(matrixP, matrixMv, tmpMatrix, 0);
- frustum.updateByPMV(tmpMatrix, 0);
+ FloatUtil.multMatrix(matrixArray, mP_offset, matrixArray, mMv_offset, mat4Tmp1, 0);
+ // FloatUtil.multMatrix(matrixP, matrixMv, mat4Tmp1, 0);
+ frustum.updateByPMV(mat4Tmp1, 0);
dirtyBits &= ~DIRTY_FRUSTUM;
mod = true;
}
@@ -1003,82 +1020,42 @@ public class PMVMatrix implements GLMatrixFunc {
return mod; // nothing more requested which may have been dirty
}
- if(nioBackupArraySupported>=0) {
- try {
- nioBackupArraySupported = 1;
- return setMviMvitNIOBackupArray() || mod;
- } catch(UnsupportedOperationException uoe) {
- nioBackupArraySupported = -1;
- }
- }
- return setMviMvitNIODirectAccess() || mod;
+ return setMviMvit() || mod;
}
//
// private
//
- private int nioBackupArraySupported = 0; // -1 not supported, 0 - TBD, 1 - supported
- private final String msgCantComputeInverse = "Invalid source Mv matrix, can't compute inverse";
+ private static final String msgCantComputeInverse = "Invalid source Mv matrix, can't compute inverse";
- private final boolean setMviMvitNIOBackupArray() {
+ private final boolean setMviMvit() {
final float[] _matrixMvi = matrixMvi.array();
final int _matrixMviOffset = matrixMvi.position();
boolean res = false;
if( 0 != ( dirtyBits & DIRTY_INVERSE_MODELVIEW ) ) { // only if dirt; always requested at this point, see update()
- if(!projectFloat.gluInvertMatrixf(matrixMv.array(), matrixMv.position(), _matrixMvi, _matrixMviOffset)) {
+ if( null == FloatUtil.invertMatrix(matrixArray, mMv_offset, _matrixMvi, _matrixMviOffset, mat4Tmp1) ) {
throw new GLException(msgCantComputeInverse);
}
dirtyBits &= ~DIRTY_INVERSE_MODELVIEW;
res = true;
}
if( 0 != ( requestMask & ( dirtyBits & DIRTY_INVERSE_TRANSPOSED_MODELVIEW ) ) ) { // only if requested & dirty
- // transpose matrix
- final float[] _matrixMvit = matrixMvit.array();
- final int _matrixMvitOffset = matrixMvit.position();
- for (int i = 0; i < 4; i++) {
- for (int j = 0; j < 4; j++) {
- _matrixMvit[_matrixMvitOffset+j+i*4] = _matrixMvi[_matrixMviOffset+i+j*4];
- }
- }
- dirtyBits &= ~DIRTY_INVERSE_TRANSPOSED_MODELVIEW;
- res = true;
- }
- return res;
- }
-
- private final boolean setMviMvitNIODirectAccess() {
- boolean res = false;
- if( 0 != ( dirtyBits & DIRTY_INVERSE_MODELVIEW ) ) { // only if dirt; always requested at this point, see update()
- if(!projectFloat.gluInvertMatrixf(matrixMv, matrixMvi)) {
- throw new GLException(msgCantComputeInverse);
- }
- dirtyBits &= ~DIRTY_INVERSE_MODELVIEW;
- res = true;
- }
- if( 0 != ( requestMask & ( dirtyBits & DIRTY_INVERSE_TRANSPOSED_MODELVIEW ) ) ) { // only if requested & dirty
- // transpose matrix
- for (int i = 0; i < 4; i++) {
- for (int j = 0; j < 4; j++) {
- matrixMvit.put(j+i*4, matrixMvi.get(i+j*4));
- }
- }
+ FloatUtil.transposeMatrix(_matrixMvi, _matrixMviOffset, matrixMvit.array(), matrixMvit.position());
dirtyBits &= ~DIRTY_INVERSE_TRANSPOSED_MODELVIEW;
res = true;
}
return res;
}
- protected final boolean usesBackingArray;
- protected final float[] matrixBufferArray;
- protected final Buffer matrixBuffer;
- protected final FloatBuffer matrixIdent, matrixPMvMvit, matrixPMvMvi, matrixPMv, matrixP, matrixTex, matrixMv, matrixMvi, matrixMvit;
- protected final float[] matrixMult, matrixTrans, matrixRot, matrixScale, matrixOrtho, matrixFrustum, tmpVec3f;
- protected final float[] tmpMatrix;
- protected final FloatStack matrixTStack, matrixPStack, matrixMvStack;
- protected final ProjectFloat projectFloat;
- protected int matrixMode = GL_MODELVIEW;
- protected int modifiedBits = MODIFIED_ALL;
- protected int dirtyBits = DIRTY_ALL; // contains the dirty bits, i.e. hinting for update operation
- protected int requestMask = 0; // may contain the requested dirty bits: DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW
- protected Frustum frustum;
+ private final float[] matrixArray;
+ private final int mP_offset, mMv_offset, mTex_offset;
+ private final FloatBuffer matrixPMvMvit, matrixPMvMvi, matrixPMv, matrixP, matrixTex, matrixMv, matrixMvi, matrixMvit;
+ private final float[] matrixTxSx;
+ private final float[] mat4Tmp1, mat4Tmp2, mat4Tmp3;
+ private final FloatStack matrixTStack, matrixPStack, matrixMvStack;
+ private int matrixMode = GL_MODELVIEW;
+ private int modifiedBits = MODIFIED_ALL;
+ private int dirtyBits = DIRTY_ALL; // contains the dirty bits, i.e. hinting for update operation
+ private int requestMask = 0; // may contain the requested dirty bits: DIRTY_INVERSE_MODELVIEW | DIRTY_INVERSE_TRANSPOSED_MODELVIEW
+ private Frustum frustum;
}