diff options
author | Sven Gothel <[email protected]> | 2014-06-27 18:16:43 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-06-27 18:16:43 +0200 |
commit | 0bded476868c5fdfe44502bfd55957469d0d72bb (patch) | |
tree | 8f3baefe8c7267a11dffacc4ba1814478c4b2123 /src/jogl/classes/com/jogamp/opengl/util | |
parent | 21b84da775fae5806481ecc658a207bf603126d5 (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/opengl/util')
-rw-r--r-- | src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java | 449 |
1 files changed, 213 insertions, 236 deletions
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; } |