From 0bded476868c5fdfe44502bfd55957469d0d72bb Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Fri, 27 Jun 2014 18:16:43 +0200 Subject: 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 --- .../graph/curve/opengl/VBORegion2PMSAAES2.java | 18 +- .../graph/curve/opengl/VBORegion2PVBAAES2.java | 17 +- src/jogl/classes/jogamp/opengl/ProjectFloat.java | 677 ++++++--------------- .../classes/jogamp/opengl/gl2/ProjectDouble.java | 55 +- 4 files changed, 209 insertions(+), 558 deletions(-) (limited to 'src/jogl/classes/jogamp') diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java index a9aa8cfb0..b56a69b28 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java @@ -166,8 +166,8 @@ public class VBORegion2PMSAAES2 extends GLRegion { gcu_ColorTexBBox = null; } - FloatUtil.makeIdentityf(pmvMatrix02, 0); - FloatUtil.makeIdentityf(pmvMatrix02, 16); + FloatUtil.makeIdentity(pmvMatrix02, 0); + FloatUtil.makeIdentity(pmvMatrix02, 16); gcu_PMVMatrix02 = new GLUniformData(UniformNames.gcu_PMVMatrix02, 4, 4, FloatBuffer.wrap(pmvMatrix02)); // Pass 2: @@ -288,7 +288,11 @@ public class VBORegion2PMSAAES2 extends GLRegion { private final AABBox drawWinBox = new AABBox(); private final int[] drawView = new int[] { 0, 0, 0, 0 }; - private final float[] drawTmpV3 = new float[3]; + private final float[] drawVec4Tmp0 = new float[4]; + private final float[] drawVec4Tmp1 = new float[4]; + private final float[] drawVec4Tmp2 = new float[4]; + private final float[] drawMat4PMv = new float[16]; + private final int border = 2; // surrounding border, i.e. width += 2*border, height +=2*border @Override @@ -328,7 +332,11 @@ public class VBORegion2PMSAAES2 extends GLRegion { // considering the sampleCount. drawView[2] = vpWidth; drawView[3] = vpHeight; - box.mapToWindow(drawWinBox, renderer.getMatrix(), drawView, true /* useCenterZ */, drawTmpV3); + + renderer.getMatrix().multPMvMatrixf(drawMat4PMv, 0); + box.mapToWindow(drawWinBox, drawMat4PMv, drawView, true /* useCenterZ */, + drawVec4Tmp0, drawVec4Tmp1, drawVec4Tmp2); + winWidth = drawWinBox.getWidth(); winHeight = drawWinBox.getHeight(); targetWinWidth = (int)Math.ceil(winWidth); @@ -392,7 +400,7 @@ public class VBORegion2PMSAAES2 extends GLRegion { fb.position(12); } gca_FboVerticesAttr.seal(true); - FloatUtil.makeOrthof(pmvMatrix02, 0, true, minX, maxX, minY, maxY, -1, 1); + FloatUtil.makeOrtho(pmvMatrix02, 0, true, minX, maxX, minY, maxY, -1, 1); useShaderProgram(gl, renderer, getRenderModes(), true, getQuality(), sampleCount[0]); renderRegion2FBO(gl, rs, targetFboWidth, targetFboHeight, vpWidth, vpHeight, sampleCount); } else if( isStateDirty() ) { diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java index 68a7b6dbd..861d889c1 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java @@ -201,8 +201,8 @@ public class VBORegion2PVBAAES2 extends GLRegion { gcu_ColorTexBBox = null; } - FloatUtil.makeIdentityf(pmvMatrix02, 0); - FloatUtil.makeIdentityf(pmvMatrix02, 16); + FloatUtil.makeIdentity(pmvMatrix02, 0); + FloatUtil.makeIdentity(pmvMatrix02, 16); gcu_PMVMatrix02 = new GLUniformData(UniformNames.gcu_PMVMatrix02, 4, 4, FloatBuffer.wrap(pmvMatrix02)); // Pass 2: @@ -333,7 +333,10 @@ public class VBORegion2PVBAAES2 extends GLRegion { private final AABBox drawWinBox = new AABBox(); private final int[] drawView = new int[] { 0, 0, 0, 0 }; - private final float[] drawTmpV3 = new float[3]; + private final float[] drawVec4Tmp0 = new float[4]; + private final float[] drawVec4Tmp1 = new float[4]; + private final float[] drawVec4Tmp2 = new float[4]; + private final float[] drawMat4PMv = new float[16]; private final int border = 2; // surrounding border, i.e. width += 2*border, height +=2*border @Override @@ -373,7 +376,11 @@ public class VBORegion2PVBAAES2 extends GLRegion { // considering the sampleCount. drawView[2] = vpWidth; drawView[3] = vpHeight; - box.mapToWindow(drawWinBox, renderer.getMatrix(), drawView, true /* useCenterZ */, drawTmpV3); + + renderer.getMatrix().multPMvMatrixf(drawMat4PMv, 0); + box.mapToWindow(drawWinBox, drawMat4PMv, drawView, true /* useCenterZ */, + drawVec4Tmp0, drawVec4Tmp1, drawVec4Tmp2); + winWidth = drawWinBox.getWidth(); winHeight = drawWinBox.getHeight(); targetWinWidth = (int)Math.ceil(winWidth); @@ -512,7 +519,7 @@ public class VBORegion2PVBAAES2 extends GLRegion { fb.position(12); } gca_FboVerticesAttr.seal(true); - FloatUtil.makeOrthof(pmvMatrix02, 0, true, minX, maxX, minY, maxY, -1, 1); + FloatUtil.makeOrtho(pmvMatrix02, 0, true, minX, maxX, minY, maxY, -1, 1); useShaderProgram(gl, renderer, getRenderModes(), true, getQuality(), sampleCount[0]); renderRegion2FBO(gl, rs, targetFboWidth, targetFboHeight, newFboWidth, newFboHeight, vpWidth, vpHeight, sampleCount[0]); } else if( isStateDirty() ) { diff --git a/src/jogl/classes/jogamp/opengl/ProjectFloat.java b/src/jogl/classes/jogamp/opengl/ProjectFloat.java index 2e5677bd4..00d1cb64b 100644 --- a/src/jogl/classes/jogamp/opengl/ProjectFloat.java +++ b/src/jogl/classes/jogamp/opengl/ProjectFloat.java @@ -115,15 +115,12 @@ */ package jogamp.opengl; -import java.nio.Buffer; import java.nio.FloatBuffer; import java.nio.IntBuffer; import javax.media.opengl.fixedfunc.GLMatrixFunc; -import com.jogamp.common.nio.Buffers; import com.jogamp.opengl.math.FloatUtil; -import com.jogamp.opengl.math.VectorUtil; /** * ProjectFloat.java @@ -146,194 +143,13 @@ public class ProjectFloat { // simpler) to simply have the array-based entry points delegate to // the versions taking Buffers by wrapping the arrays. - // Array-based implementation - private final float[] matrix = new float[16]; - private final float[][] tempInvertMatrix = new float[4][4]; - - private final float[] in = new float[4]; - private final float[] out = new float[4]; - - // Buffer-based implementation - private FloatBuffer matrixBuf; // 4x4 - - private final float[] forward = new float[3]; // 3 - private final float[] side = new float[3]; // 3 - private final float[] up = new float[3]; // 3 + private final float[] mat4Tmp1 = new float[16]; + private final float[] mat4Tmp2 = new float[16]; + private final float[] mat4Tmp3 = new float[16]; public ProjectFloat() { - this(true); - } - - public ProjectFloat(boolean useBackingArray) { - this(useBackingArray ? null : Buffers.newDirectByteBuffer(getRequiredFloatBufferSize() * Buffers.SIZEOF_FLOAT), - useBackingArray ? new float[getRequiredFloatBufferSize()] : null, - 0); - } - - /** - * @param floatBuffer source buffer, may be ByteBuffer (recommended) or FloatBuffer or null. - * If used, shall be ≥ {@link #getRequiredFloatBufferSize()} + floatOffset. - * Buffer's position is ignored and floatPos is being used. - * @param floatArray source float array or null. - * If used, size shall be ≥ {@link #getRequiredFloatBufferSize()} + floatOffset. - * @param floatOffset Offset for either of the given sources (buffer or array) - */ - public ProjectFloat(Buffer floatBuffer, float[] floatArray, int floatOffset) { - matrixBuf = Buffers.slice2Float(floatBuffer, floatArray, floatOffset, 16); - } - - public void destroy() { - matrixBuf = null; - } - - /** - * @param src - * @param srcOffset - * @param inverse - * @param inverseOffset - * @return - */ - public boolean gluInvertMatrixf(float[] src, int srcOffset, float[] inverse, int inverseOffset) { - int i, j, k, swap; - float t; - final float[][] temp = tempInvertMatrix; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - temp[i][j] = src[i*4+j+srcOffset]; - } - } - FloatUtil.makeIdentityf(inverse, inverseOffset); - - for (i = 0; i < 4; i++) { - // - // Look for largest element in column - // - swap = i; - for (j = i + 1; j < 4; j++) { - if (Math.abs(temp[j][i]) > Math.abs(temp[i][i])) { - swap = j; - } - } - - if (swap != i) { - // - // Swap rows. - // - for (k = 0; k < 4; k++) { - t = temp[i][k]; - temp[i][k] = temp[swap][k]; - temp[swap][k] = t; - - t = inverse[i*4+k+inverseOffset]; - inverse[i*4+k+inverseOffset] = inverse[swap*4+k+inverseOffset]; - inverse[swap*4+k+inverseOffset] = t; - } - } - - if (temp[i][i] == 0) { - // - // No non-zero pivot. The matrix is singular, which shouldn't - // happen. This means the user gave us a bad matrix. - // - return false; - } - - t = temp[i][i]; - for (k = 0; k < 4; k++) { - temp[i][k] /= t; - inverse[i*4+k+inverseOffset] /= t; - } - for (j = 0; j < 4; j++) { - if (j != i) { - t = temp[j][i]; - for (k = 0; k < 4; k++) { - temp[j][k] -= temp[i][k] * t; - inverse[j*4+k+inverseOffset] -= inverse[i*4+k+inverseOffset]*t; - } - } - } - } - return true; } - /** - * @param src - * @param inverse - * - * @return - */ - public boolean gluInvertMatrixf(FloatBuffer src, FloatBuffer inverse) { - int i, j, k, swap; - float t; - - final int srcPos = src.position(); - final int invPos = inverse.position(); - - final float[][] temp = tempInvertMatrix; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - temp[i][j] = src.get(i*4+j + srcPos); - } - } - FloatUtil.makeIdentityf(inverse); - - for (i = 0; i < 4; i++) { - // - // Look for largest element in column - // - swap = i; - for (j = i + 1; j < 4; j++) { - if (Math.abs(temp[j][i]) > Math.abs(temp[i][i])) { - swap = j; - } - } - - if (swap != i) { - // - // Swap rows. - // - for (k = 0; k < 4; k++) { - t = temp[i][k]; - temp[i][k] = temp[swap][k]; - temp[swap][k] = t; - - t = inverse.get(i*4+k + invPos); - inverse.put(i*4+k + invPos, inverse.get(swap*4+k + invPos)); - inverse.put(swap*4+k + invPos, t); - } - } - - if (temp[i][i] == 0) { - // - // No non-zero pivot. The matrix is singular, which shouldn't - // happen. This means the user gave us a bad matrix. - // - return false; - } - - t = temp[i][i]; - for (k = 0; k < 4; k++) { - temp[i][k] /= t; - final int z = i*4+k + invPos; - inverse.put(z, inverse.get(z) / t); - } - for (j = 0; j < 4; j++) { - if (j != i) { - t = temp[j][i]; - for (k = 0; k < 4; k++) { - temp[j][k] -= temp[i][k] * t; - final int z = j*4+k + invPos; - inverse.put(z, inverse.get(z) - inverse.get(i*4+k + invPos) * t); - } - } - } - } - return true; - } - - /** * Method gluOrtho2D. * @@ -349,34 +165,13 @@ public class ProjectFloat { /** * Method gluPerspective. * - * @param fovy + * @param fovy angle in degrees * @param aspect * @param zNear * @param zFar */ public void gluPerspective(GLMatrixFunc gl, float fovy, float aspect, float zNear, float zFar) { - final float radians = fovy / 2 * (float) Math.PI / 180; - float sine, cotangent, deltaZ; - - deltaZ = zFar - zNear; - sine = (float) Math.sin(radians); - - if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) { - return; - } - - cotangent = (float) Math.cos(radians) / sine; - - FloatUtil.makeIdentityf(matrixBuf); - final int mPos = matrixBuf.position(); - matrixBuf.put(0 * 4 + 0 + mPos, cotangent / aspect); - matrixBuf.put(1 * 4 + 1 + mPos, cotangent); - matrixBuf.put(2 * 4 + 2 + mPos, - (zFar + zNear) / deltaZ); - matrixBuf.put(2 * 4 + 3 + mPos, -1); - matrixBuf.put(3 * 4 + 2 + mPos, -2 * zNear * zFar / deltaZ); - matrixBuf.put(3 * 4 + 3 + mPos, 0); - - gl.glMultMatrixf(matrixBuf); + gl.glMultMatrixf(FloatUtil.makePerspective(mat4Tmp1, 0, true, fovy / 2 * (float) Math.PI / 180, aspect, zNear, zFar), 0); } /** @@ -396,92 +191,45 @@ public class ProjectFloat { float eyex, float eyey, float eyez, float centerx, float centery, float centerz, float upx, float upy, float upz) { - final float[] forward = this.forward; - final float[] side = this.side; - final float[] up = this.up; - - forward[0] = centerx - eyex; - forward[1] = centery - eyey; - forward[2] = centerz - eyez; - - up[0] = upx; - up[1] = upy; - up[2] = upz; - - VectorUtil.normalizeVec3(forward); - - /* Side = forward x up */ - VectorUtil.crossVec3(side, forward, up); - VectorUtil.normalizeVec3(side); - - /* Recompute up as: up = side x forward */ - VectorUtil.crossVec3(up, side, forward); - - FloatUtil.makeIdentityf(matrixBuf); - final int mPos = matrixBuf.position(); - matrixBuf.put(0 * 4 + 0 + mPos, side[0]); - matrixBuf.put(1 * 4 + 0 + mPos, side[1]); - matrixBuf.put(2 * 4 + 0 + mPos, side[2]); - - matrixBuf.put(0 * 4 + 1 + mPos, up[0]); - matrixBuf.put(1 * 4 + 1 + mPos, up[1]); - matrixBuf.put(2 * 4 + 1 + mPos, up[2]); - - matrixBuf.put(0 * 4 + 2 + mPos, -forward[0]); - matrixBuf.put(1 * 4 + 2 + mPos, -forward[1]); - matrixBuf.put(2 * 4 + 2 + mPos, -forward[2]); - - gl.glMultMatrixf(matrixBuf); - gl.glTranslatef(-eyex, -eyey, -eyez); + 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; + gl.glMultMatrixf( + FloatUtil.makeLookAt(mat4Tmp1, 0, mat4Tmp2 /* eye */, 0, mat4Tmp2 /* center */, 4, mat4Tmp2 /* up */, 8, mat4Tmp3), 0); } /** * Map object coordinates to window coordinates. + *

+ * Traditional gluProject implementation. + *

* * @param objx * @param objy * @param objz - * @param modelMatrix - * @param projMatrix - * @param viewport - * @param win_pos - * - * @return + * @param viewport 4 component viewport vector + * @param viewport_offset + * @param win_pos 3 component window coordinate, the result + * @param win_pos_offset + * @return true if successful, otherwise false (z is 1) */ - public boolean gluProject(float objx, float objy, float objz, - float[] modelMatrix, int modelMatrix_offset, - float[] projMatrix, int projMatrix_offset, - int[] viewport, int viewport_offset, - float[] win_pos, int win_pos_offset ) { - - final float[] in = this.in; - final float[] out = this.out; - - in[0] = objx; - in[1] = objy; - in[2] = objz; - in[3] = 1.0f; - - FloatUtil.multMatrixVecf(modelMatrix, modelMatrix_offset, in, 0, out, 0); - FloatUtil.multMatrixVecf(projMatrix, projMatrix_offset, out, 0, in, 0); - - if (in[3] == 0.0f) { - return false; - } - - in[3] = (1.0f / in[3]) * 0.5f; - - // Map x, y and z to range 0-1 - in[0] = in[0] * in[3] + 0.5f; - in[1] = in[1] * in[3] + 0.5f; - in[2] = in[2] * in[3] + 0.5f; - - // Map x,y to viewport - win_pos[0+win_pos_offset] = in[0] * viewport[2+viewport_offset] + viewport[0+viewport_offset]; - win_pos[1+win_pos_offset] = in[1] * viewport[3+viewport_offset] + viewport[1+viewport_offset]; - win_pos[2+win_pos_offset] = in[2]; - - return true; + public boolean gluProject(final float objx, final float objy, final float objz, + final float[] modelMatrix, final int modelMatrix_offset, + final float[] projMatrix, final int projMatrix_offset, + final int[] viewport, final int viewport_offset, + final float[] win_pos, final int win_pos_offset ) { + return FloatUtil.mapObjToWinCoords(objx, objy, objz, + modelMatrix, modelMatrix_offset, + projMatrix, projMatrix_offset, + viewport, viewport_offset, + win_pos, win_pos_offset, + mat4Tmp1, mat4Tmp2); } /** @@ -492,17 +240,16 @@ public class ProjectFloat { FloatBuffer projMatrix, int[] viewport, int viewport_offset, float[] win_pos, int win_pos_offset ) { - - final float[] in = this.in; - final float[] out = this.out; + final float[] in = this.mat4Tmp1; + final float[] out = this.mat4Tmp2; in[0] = objx; in[1] = objy; in[2] = objz; in[3] = 1.0f; - FloatUtil.multMatrixVecf(modelMatrix, in, out); - FloatUtil.multMatrixVecf(projMatrix, out, in); + FloatUtil.multMatrixVec(modelMatrix, in, out); + FloatUtil.multMatrixVec(projMatrix, out, in); if (in[3] == 0.0f) { return false; @@ -542,16 +289,16 @@ public class ProjectFloat { IntBuffer viewport, FloatBuffer win_pos) { - final float[] in = this.in; - final float[] out = this.out; + final float[] in = this.mat4Tmp1; + final float[] out = this.mat4Tmp2; in[0] = objx; in[1] = objy; in[2] = objz; in[3] = 1.0f; - FloatUtil.multMatrixVecf(modelMatrix, in, out); - FloatUtil.multMatrixVecf(projMatrix, out, in); + FloatUtil.multMatrixVec(modelMatrix, in, out); + FloatUtil.multMatrixVec(projMatrix, out, in); if (in[3] == 0.0f) { return false; @@ -577,58 +324,30 @@ public class ProjectFloat { /** * Map window coordinates to object coordinates. + *

+ * Traditional gluUnProject implementation. + *

* * @param winx * @param winy * @param winz - * @param modelMatrix - * @param projMatrix - * @param viewport - * @param obj_pos - * - * @return true if successful, otherwise false (failed to invert matrix, or becomes z is infinity) + * @param viewport 4 component viewport vector + * @param viewport_offset + * @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 infinity due to zero z) */ public boolean gluUnProject(float winx, float winy, float winz, float[] modelMatrix, int modelMatrix_offset, float[] projMatrix, int projMatrix_offset, int[] viewport, int viewport_offset, float[] obj_pos, int obj_pos_offset) { - final float[] in = this.in; - final float[] out = this.out; - - FloatUtil.multMatrixf(projMatrix, projMatrix_offset, modelMatrix, modelMatrix_offset, matrix, 0); - - if (!gluInvertMatrixf(matrix, 0, matrix, 0)) { - return false; - } - - in[0] = winx; - in[1] = winy; - in[2] = winz; - in[3] = 1.0f; - - // Map x and y from window coordinates - in[0] = (in[0] - viewport[0+viewport_offset]) / viewport[2+viewport_offset]; - in[1] = (in[1] - viewport[1+viewport_offset]) / viewport[3+viewport_offset]; - - // Map to range -1 to 1 - in[0] = in[0] * 2 - 1; - in[1] = in[1] * 2 - 1; - in[2] = in[2] * 2 - 1; - - FloatUtil.multMatrixVecf(matrix, in, out); - - if (out[3] == 0.0) { - return false; - } - - out[3] = 1.0f / out[3]; - - obj_pos[0+obj_pos_offset] = out[0] * out[3]; - obj_pos[1+obj_pos_offset] = out[1] * out[3]; - obj_pos[2+obj_pos_offset] = out[2] * out[3]; - - return true; + return FloatUtil.mapWinToObjCoords(winx, winy, winz, + modelMatrix, modelMatrix_offset, + projMatrix, projMatrix_offset, + viewport, viewport_offset, + obj_pos, obj_pos_offset, + mat4Tmp1, mat4Tmp2); } @@ -646,45 +365,46 @@ public class ProjectFloat { * @param obj_pos_offset * @return true if successful, otherwise false (failed to invert matrix, or becomes z is infinity) */ - public boolean gluUnProject(float winx, float winy, float winz, - FloatBuffer modelMatrix, - FloatBuffer projMatrix, - int[] viewport, int viewport_offset, - float[] obj_pos, int obj_pos_offset) { - final float[] in = this.in; - final float[] out = this.out; - - FloatUtil.multMatrixf(projMatrix, modelMatrix, matrixBuf); - - if (!gluInvertMatrixf(matrixBuf, matrixBuf)) { + public boolean gluUnProject(final float winx, final float winy, final float winz, + final FloatBuffer modelMatrix, + final FloatBuffer projMatrix, + final int[] viewport, final int viewport_offset, + final float[] obj_pos, final int obj_pos_offset) { + // mat4Tmp1 = P x M + FloatUtil.multMatrix(projMatrix, modelMatrix, mat4Tmp1); + + // mat4Tmp1 = Inv(P x M) + if ( null == FloatUtil.invertMatrix(mat4Tmp1, 0, mat4Tmp1, 0, mat4Tmp2) ) { return false; } - in[0] = winx; - in[1] = winy; - in[2] = winz; - in[3] = 1.0f; + mat4Tmp2[0] = winx; + mat4Tmp2[1] = winy; + mat4Tmp2[2] = winz; + mat4Tmp2[3] = 1.0f; // Map x and y from window coordinates - in[0] = (in[0] - viewport[0+viewport_offset]) / viewport[2+viewport_offset]; - in[1] = (in[1] - viewport[1+viewport_offset]) / viewport[3+viewport_offset]; + 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 - in[0] = in[0] * 2 - 1; - in[1] = in[1] * 2 - 1; - in[2] = in[2] * 2 - 1; + mat4Tmp2[0] = mat4Tmp2[0] * 2 - 1; + mat4Tmp2[1] = mat4Tmp2[1] * 2 - 1; + mat4Tmp2[2] = mat4Tmp2[2] * 2 - 1; - FloatUtil.multMatrixVecf(matrixBuf, in, out); + final int raw_off = 4; + // object raw coords = Inv(P x M) * winPos -> mat4Tmp2 + FloatUtil.multMatrixVec(mat4Tmp1, 0, mat4Tmp2, 0, mat4Tmp2, raw_off); - if (out[3] == 0.0) { + if (mat4Tmp2[3+raw_off] == 0.0) { return false; } - out[3] = 1.0f / out[3]; + mat4Tmp2[3+raw_off] = 1.0f / mat4Tmp2[3+raw_off]; - obj_pos[0+obj_pos_offset] = out[0] * out[3]; - obj_pos[1+obj_pos_offset] = out[1] * out[3]; - obj_pos[2+obj_pos_offset] = out[2] * out[3]; + 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; } @@ -707,42 +427,44 @@ public class ProjectFloat { FloatBuffer projMatrix, IntBuffer viewport, FloatBuffer obj_pos) { - final float[] in = this.in; - final float[] out = this.out; + final int vPos = viewport.position(); + final int oPos = obj_pos.position(); - FloatUtil.multMatrixf(projMatrix, modelMatrix, matrixBuf); + // mat4Tmp1 = P x M + FloatUtil.multMatrix(projMatrix, modelMatrix, mat4Tmp1); - if (!gluInvertMatrixf(matrixBuf, matrixBuf)) { + // mat4Tmp1 = Inv(P x M) + if ( null == FloatUtil.invertMatrix(mat4Tmp1, 0, mat4Tmp1, 0, mat4Tmp2) ) { return false; } - in[0] = winx; - in[1] = winy; - in[2] = winz; - in[3] = 1.0f; + mat4Tmp2[0] = winx; + mat4Tmp2[1] = winy; + mat4Tmp2[2] = winz; + mat4Tmp2[3] = 1.0f; // Map x and y from window coordinates - final int vPos = viewport.position(); - final int oPos = obj_pos.position(); - in[0] = (in[0] - viewport.get(0+vPos)) / viewport.get(2+vPos); - in[1] = (in[1] - viewport.get(1+vPos)) / viewport.get(3+vPos); + mat4Tmp2[0] = (mat4Tmp2[0] - viewport.get(0+vPos)) / viewport.get(2+vPos); + mat4Tmp2[1] = (mat4Tmp2[1] - viewport.get(1+vPos)) / viewport.get(3+vPos); // Map to range -1 to 1 - in[0] = in[0] * 2 - 1; - in[1] = in[1] * 2 - 1; - in[2] = in[2] * 2 - 1; + mat4Tmp2[0] = mat4Tmp2[0] * 2 - 1; + mat4Tmp2[1] = mat4Tmp2[1] * 2 - 1; + mat4Tmp2[2] = mat4Tmp2[2] * 2 - 1; - FloatUtil.multMatrixVecf(matrixBuf, in, out); + final int raw_off = 4; + // object raw coords = Inv(P x M) * winPos -> mat4Tmp2 + FloatUtil.multMatrixVec(mat4Tmp1, 0, mat4Tmp2, 0, mat4Tmp2, raw_off); - if (out[3] == 0.0) { + if (mat4Tmp2[3+raw_off] == 0.0) { return false; } - out[3] = 1.0f / out[3]; + mat4Tmp2[3+raw_off] = 1.0f / mat4Tmp2[3+raw_off]; - obj_pos.put(0+oPos, out[0] * out[3]); - obj_pos.put(1+oPos, out[1] * out[3]); - obj_pos.put(2+oPos, out[2] * out[3]); + obj_pos.put(0+oPos, mat4Tmp2[0+raw_off] * mat4Tmp2[3+raw_off]); + obj_pos.put(1+oPos, mat4Tmp2[1+raw_off] * mat4Tmp2[3+raw_off]); + obj_pos.put(2+oPos, mat4Tmp2[2+raw_off] * mat4Tmp2[3+raw_off]); return true; } @@ -750,68 +472,39 @@ public class ProjectFloat { /** * Map window coordinates to object coordinates. + *

+ * Traditional gluUnProject4 implementation. + *

* * @param winx * @param winy * @param winz * @param clipw - * @param modelMatrix - * @param projMatrix - * @param viewport + * @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 - * - * @return true if successful, otherwise false (failed to invert matrix, or becomes z is infinity) + * @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(float winx, - float winy, - float winz, - 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[] in = this.in; - final float[] out = this.out; - - FloatUtil.multMatrixf(projMatrix, projMatrix_offset, modelMatrix, modelMatrix_offset, matrix, 0); - - if (!gluInvertMatrixf(matrix, 0, matrix, 0)) - return false; - - in[0] = winx; - in[1] = winy; - in[2] = winz; - in[3] = clipw; - - // Map x and y from window coordinates - in[0] = (in[0] - viewport[0+viewport_offset]) / viewport[2+viewport_offset]; - in[1] = (in[1] - viewport[1+viewport_offset]) / viewport[3+viewport_offset]; - in[2] = (in[2] - near) / (far - near); - - // Map to range -1 to 1 - in[0] = in[0] * 2 - 1; - in[1] = in[1] * 2 - 1; - in[2] = in[2] * 2 - 1; - - FloatUtil.multMatrixVecf(matrix, in, out); - - if (out[3] == 0.0f) { - return false; - } - - obj_pos[0+obj_pos_offset] = out[0]; - obj_pos[1+obj_pos_offset] = out[1]; - obj_pos[2+obj_pos_offset] = out[2]; - obj_pos[3+obj_pos_offset] = out[3]; - return true; + public boolean gluUnProject4(final float winx, final float winy, final float winz, final float clipw, + final float[] modelMatrix, final int modelMatrix_offset, + final float[] projMatrix, final int projMatrix_offset, + final int[] viewport, final int viewport_offset, + final float near, final float far, + final float[] obj_pos, final int obj_pos_offset ) { + return FloatUtil.mapWinToObjCoords(winx, winy, winz, clipw, + modelMatrix, modelMatrix_offset, + projMatrix, projMatrix_offset, + viewport, viewport_offset, + near, far, + obj_pos, obj_pos_offset, + mat4Tmp1, mat4Tmp2); } /** @@ -830,70 +523,65 @@ public class ProjectFloat { * * @return true if successful, otherwise false (failed to invert matrix, or becomes z is infinity) */ - public boolean gluUnProject4(float winx, - float winy, - float winz, - float clipw, - FloatBuffer modelMatrix, - FloatBuffer projMatrix, - IntBuffer viewport, - float near, - float far, - FloatBuffer obj_pos) { - final float[] in = this.in; - final float[] out = this.out; - - FloatUtil.multMatrixf(projMatrix, modelMatrix, matrixBuf); - - if (!gluInvertMatrixf(matrixBuf, matrixBuf)) + public boolean gluUnProject4(final float winx, final float winy, final float winz, final float clipw, + final FloatBuffer modelMatrix, final FloatBuffer projMatrix, + final IntBuffer viewport, + final float near, final float far, + final FloatBuffer obj_pos) { + FloatUtil.multMatrix(projMatrix, modelMatrix, mat4Tmp1); + + if ( null == FloatUtil.invertMatrix(mat4Tmp1, 0, mat4Tmp1, 0, mat4Tmp2) ) { return false; + } - in[0] = winx; - in[1] = winy; - in[2] = winz; - in[3] = clipw; + mat4Tmp2[0] = winx; + mat4Tmp2[1] = winy; + mat4Tmp2[2] = winz; + mat4Tmp2[3] = clipw; // Map x and y from window coordinates final int vPos = viewport.position(); - in[0] = (in[0] - viewport.get(0+vPos)) / viewport.get(2+vPos); - in[1] = (in[1] - viewport.get(1+vPos)) / viewport.get(3+vPos); - in[2] = (in[2] - near) / (far - near); + mat4Tmp2[0] = (mat4Tmp2[0] - viewport.get(0+vPos)) / viewport.get(2+vPos); + mat4Tmp2[1] = (mat4Tmp2[1] - viewport.get(1+vPos)) / viewport.get(3+vPos); + mat4Tmp2[2] = (mat4Tmp2[2] - near) / (far - near); // Map to range -1 to 1 - in[0] = in[0] * 2 - 1; - in[1] = in[1] * 2 - 1; - in[2] = in[2] * 2 - 1; + mat4Tmp2[0] = mat4Tmp2[0] * 2 - 1; + mat4Tmp2[1] = mat4Tmp2[1] * 2 - 1; + mat4Tmp2[2] = mat4Tmp2[2] * 2 - 1; - FloatUtil.multMatrixVecf(matrixBuf, in, out); + final int raw_off = 4; + FloatUtil.multMatrixVec(mat4Tmp1, 0, mat4Tmp2, 0, mat4Tmp2, raw_off); - if (out[3] == 0.0f) { + if (mat4Tmp2[3+raw_off] == 0.0f) { return false; } final int oPos = obj_pos.position(); - obj_pos.put(0+oPos, out[0]); - obj_pos.put(1+oPos, out[1]); - obj_pos.put(2+oPos, out[2]); - obj_pos.put(3+oPos, out[3]); + obj_pos.put(0+oPos, mat4Tmp2[0+raw_off]); + obj_pos.put(1+oPos, mat4Tmp2[1+raw_off]); + obj_pos.put(2+oPos, mat4Tmp2[2+raw_off]); + obj_pos.put(3+oPos, mat4Tmp2[3+raw_off]); return true; } /** - * Method gluPickMatrix - * + * Make given matrix the pick matrix based on given parameters. + *

+ * Traditional gluPickMatrix implementation. + *

* @param x * @param y * @param deltaX * @param deltaY - * @param viewport + * @param viewport 4 component viewport vector + * @param viewport_offset */ - public void gluPickMatrix(GLMatrixFunc gl, - float x, - float y, - float deltaX, - float deltaY, - IntBuffer viewport) { + public void gluPickMatrix(final GLMatrixFunc gl, + final float x, final float y, + float deltaX, final float deltaY, + final IntBuffer viewport) { if (deltaX <= 0 || deltaY <= 0) { return; } @@ -907,31 +595,24 @@ public class ProjectFloat { } /** - * Method gluPickMatrix - * + * Make given matrix the pick matrix based on given parameters. + *

+ * Traditional gluPickMatrix implementation. + *

* @param x * @param y * @param deltaX * @param deltaY - * @param viewport + * @param viewport 4 component viewport vector * @param viewport_offset */ - public void gluPickMatrix(GLMatrixFunc gl, - float x, - float y, - float deltaX, - float deltaY, - int[] viewport, - int viewport_offset) { - if (deltaX <= 0 || deltaY <= 0) { - return; + public void gluPickMatrix(final GLMatrixFunc gl, + final float x, final float y, + final float deltaX, final float deltaY, + final int[] viewport, final int viewport_offset) { + if( null != FloatUtil.makePick(mat4Tmp1, 0, x, y, deltaX, deltaY, viewport, viewport_offset, mat4Tmp2) ) { + gl.glMultMatrixf(mat4Tmp1, 0); } - - /* Translate and scale the picked region to the entire window */ - gl.glTranslatef((viewport[2+viewport_offset] - 2 * (x - viewport[0+viewport_offset])) / deltaX, - (viewport[3+viewport_offset] - 2 * (y - viewport[1+viewport_offset])) / deltaY, - 0); - gl.glScalef(viewport[2+viewport_offset] / deltaX, viewport[3+viewport_offset] / deltaY, 1.0f); } } diff --git a/src/jogl/classes/jogamp/opengl/gl2/ProjectDouble.java b/src/jogl/classes/jogamp/opengl/gl2/ProjectDouble.java index a4aa1c7c5..e0ec0f401 100644 --- a/src/jogl/classes/jogamp/opengl/gl2/ProjectDouble.java +++ b/src/jogl/classes/jogamp/opengl/gl2/ProjectDouble.java @@ -114,10 +114,11 @@ */ package jogamp.opengl.gl2; -import java.nio.*; +import java.nio.DoubleBuffer; +import java.nio.IntBuffer; + +import javax.media.opengl.GL2; -import javax.media.opengl.*; -import jogamp.opengl.*; import com.jogamp.common.nio.Buffers; /** @@ -152,12 +153,7 @@ public class ProjectDouble { private final double[] in = new double[4]; private final double[] out = new double[4]; - private final double[] forward = new double[3]; - private final double[] side = new double[3]; - private final double[] up = new double[3]; - // Buffer-based implementation - private DoubleBuffer locbuf; private final DoubleBuffer matrixBuf; private final DoubleBuffer tempMatrixBuf; @@ -174,7 +170,7 @@ public class ProjectDouble { // Slice up one big buffer because some NIO implementations // allocate a huge amount of memory to back even the smallest of // buffers. - DoubleBuffer locbuf = Buffers.newDirectDoubleBuffer(128); + final DoubleBuffer locbuf = Buffers.newDirectDoubleBuffer(128); int pos = 0; int sz = 16; matrixBuf = slice(locbuf, pos, sz); @@ -194,13 +190,6 @@ public class ProjectDouble { upBuf = slice(locbuf, pos, sz); } - public void destroy() { - if(locbuf!=null) { - locbuf.clear(); - locbuf=null; - } - } - private static DoubleBuffer slice(DoubleBuffer buf, int pos, int len) { buf.position(pos); buf.limit(pos + len); @@ -446,27 +435,6 @@ public class ProjectDouble { } } - /** - * Normalize vector - * - * @param v - */ - private static void normalize(double[] v) { - double r; - - r = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); - if ( r == 0.0 ) - return; - - r = 1.0 / r; - - v[0] *= r; - v[1] *= r; - v[2] *= r; - - return; - } - /** * Normalize vector * @@ -493,19 +461,6 @@ public class ProjectDouble { } - /** - * Calculate cross-product - * - * @param v1 - * @param v2 - * @param result - */ - private static void cross(double[] v1, double[] v2, double[] result) { - result[0] = v1[1] * v2[2] - v1[2] * v2[1]; - result[1] = v1[2] * v2[0] - v1[0] * v2[2]; - result[2] = v1[0] * v2[1] - v1[1] * v2[0]; - } - /** * Calculate cross-product * -- cgit v1.2.3