diff options
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/ProjectFloat.java')
-rw-r--r-- | src/jogl/classes/jogamp/opengl/ProjectFloat.java | 905 |
1 files changed, 294 insertions, 611 deletions
diff --git a/src/jogl/classes/jogamp/opengl/ProjectFloat.java b/src/jogl/classes/jogamp/opengl/ProjectFloat.java index ce8405f74..5921eb9a9 100644 --- a/src/jogl/classes/jogamp/opengl/ProjectFloat.java +++ b/src/jogl/classes/jogamp/opengl/ProjectFloat.java @@ -6,9 +6,9 @@ ** this file except in compliance with the License. You may obtain a copy ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: -** +** ** http://oss.sgi.com/projects/FreeB -** +** ** Note that, as provided in the License, the Software is distributed on an ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND @@ -24,13 +24,13 @@ ** except that Section 2.2 and 11 are omitted. Any differences between ** the Alternative License and the SGI License are offered solely by Sun ** and not by SGI. -** +** ** Original Code. The Original Code is: OpenGL Sample Implementation, ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. ** Copyright in any portions created by third parties is as indicated ** elsewhere herein. All Rights Reserved. -** +** ** Additional Notice Provisions: The application programming interfaces ** established by SGI in conjunction with the Original Code are The ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released @@ -45,34 +45,34 @@ ** $Header$ */ -/* +/* * Copyright (c) 2002-2004 LWJGL Project * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are + * modification, are permitted provided that the following conditions are * met: - * - * * Redistributions of source code must retain the above copyright + * + * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * * Neither the name of 'LWJGL' nor the names of - * its contributors may be used to endorse or promote products derived + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ @@ -80,22 +80,22 @@ /* * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. * Copyright (c) 2011 JogAmp Community. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * - Redistribution of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * - Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. - * + * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A @@ -108,35 +108,33 @@ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * + * * You acknowledge that this software is not designed or intended for use * in the design, construction, operation or maintenance of any nuclear * facility. */ 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.FloatUtil; +import com.jogamp.opengl.math.FloatUtil; /** * ProjectFloat.java * <p> * Created 11-jan-2004 * </p> - * + * * @author Erik Duijs * @author Kenneth Russell * @author Sven Gothel */ public class ProjectFloat { - public static final int getRequiredFloatBufferSize() { return 2*16+2*4+3*3; } - + public static final int getRequiredFloatBufferSize() { return 1*16; } + // Note that we have cloned parts of the implementation in order to // support incoming Buffers. The reason for this is to avoid loading // non-direct buffer subclasses unnecessarily, because doing so can @@ -145,266 +143,40 @@ 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; - private FloatBuffer tempInvertMatrixBuf; - - private FloatBuffer inBuf; - private FloatBuffer outBuf; - - private FloatBuffer forwardBuf; - private FloatBuffer sideBuf; - private FloatBuffer upBuf; + private final float[] mat4Tmp1 = new float[16]; + private final float[] mat4Tmp2 = new float[16]; + private final float[] mat4Tmp3 = new float[16]; public ProjectFloat() { - this(false); - } - - 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 <code>null</code>. - * If used, shall be ≥ {@link #getRequiredFloatBufferSize()} + floatOffset. - * Buffer's position is ignored and floatPos is being used. - * @param floatArray source float array or <code>null</code>. - * 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) { - int floatPos = floatOffset; - int floatSize = 16; - matrixBuf = Buffers.slice2Float(floatBuffer, floatArray, floatPos, floatSize); - floatPos += floatSize; - tempInvertMatrixBuf = Buffers.slice2Float(floatBuffer, floatArray, floatPos, floatSize); - floatPos += floatSize; - floatSize = 4; - inBuf = Buffers.slice2Float(floatBuffer, floatArray, floatPos, floatSize); - floatPos += floatSize; - outBuf = Buffers.slice2Float(floatBuffer, floatArray, floatPos, floatSize); - floatPos += floatSize; - floatSize = 3; - forwardBuf = Buffers.slice2Float(floatBuffer, floatArray, floatPos, floatSize); - floatPos += floatSize; - sideBuf = Buffers.slice2Float(floatBuffer, floatArray, floatPos, floatSize); - floatPos += floatSize; - upBuf = Buffers.slice2Float(floatBuffer, floatArray, floatPos, floatSize); - } - - public void destroy() { - matrixBuf = null; - tempInvertMatrixBuf = null; - inBuf = null; - outBuf = null; - forwardBuf = null; - sideBuf = null; - upBuf = 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; - 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; - - int srcPos = src.position(); - int invPos = inverse.position(); - - FloatBuffer temp = tempInvertMatrixBuf; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - temp.put(i*4+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.get(j*4+i)) > Math.abs(temp.get(i*4+i))) { - swap = j; - } - } - - if (swap != i) { - // - // Swap rows. - // - for (k = 0; k < 4; k++) { - t = temp.get(i*4+k); - temp.put(i*4+k, temp.get(swap*4+k)); - temp.put(swap*4+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.get(i*4+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.get(i*4+i); - for (k = 0; k < 4; k++) { - temp.put(i*4+k, temp.get(i*4+k) / t); - inverse.put(i*4+k + invPos, inverse.get(i*4+k + invPos) / t); - } - for (j = 0; j < 4; j++) { - if (j != i) { - t = temp.get(j*4+i); - for (k = 0; k < 4; k++) { - temp.put(j*4+k, temp.get(j*4+k) - temp.get(i*4+k) * t); - inverse.put(j*4+k + invPos, inverse.get(j*4+k + invPos) - inverse.get(i*4+k + invPos) * t); - } - } - } - } - return true; } - /** * Method gluOrtho2D. - * + * * @param left * @param right * @param bottom * @param top */ - public void gluOrtho2D(GLMatrixFunc gl, float left, float right, float bottom, float top) { + public void gluOrtho2D(final GLMatrixFunc gl, final float left, final float right, final float bottom, final float top) { gl.glOrthof(left, right, bottom, top, -1, 1); } /** * Method gluPerspective. - * - * @param fovy + * + * @param fovy_deg fov angle in degrees * @param aspect * @param zNear * @param zFar */ - public void gluPerspective(GLMatrixFunc gl, float fovy, float aspect, float zNear, float zFar) { - float sine, cotangent, deltaZ; - float radians = fovy / 2 * (float) Math.PI / 180; - - 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); - - matrixBuf.put(0 * 4 + 0, cotangent / aspect); - matrixBuf.put(1 * 4 + 1, cotangent); - matrixBuf.put(2 * 4 + 2, - (zFar + zNear) / deltaZ); - matrixBuf.put(2 * 4 + 3, -1); - matrixBuf.put(3 * 4 + 2, -2 * zNear * zFar / deltaZ); - matrixBuf.put(3 * 4 + 3, 0); - - gl.glMultMatrixf(matrixBuf); + public void gluPerspective(final GLMatrixFunc gl, final float fovy_deg, final float aspect, final float zNear, final float zFar) { + gl.glMultMatrixf(FloatUtil.makePerspective(mat4Tmp1, 0, true, fovy_deg * FloatUtil.PI / 180.0f, aspect, zNear, zFar), 0); } /** * Method gluLookAt - * + * * @param eyex * @param eyey * @param eyez @@ -415,77 +187,70 @@ public class ProjectFloat { * @param upy * @param upz */ - public void gluLookAt(GLMatrixFunc gl, - float eyex, float eyey, float eyez, - float centerx, float centery, float centerz, - float upx, float upy, float upz) { - FloatBuffer forward = this.forwardBuf; - FloatBuffer side = this.sideBuf; - FloatBuffer up = this.upBuf; - - forward.put(0, centerx - eyex); - forward.put(1, centery - eyey); - forward.put(2, centerz - eyez); - - up.put(0, upx); - up.put(1, upy); - up.put(2, upz); - - FloatUtil.normalize(forward); - - /* Side = forward x up */ - FloatUtil.cross(forward, up, side); - FloatUtil.normalize(side); - - /* Recompute up as: up = side x forward */ - FloatUtil.cross(side, forward, up); - - FloatUtil.makeIdentityf(matrixBuf); - matrixBuf.put(0 * 4 + 0, side.get(0)); - matrixBuf.put(1 * 4 + 0, side.get(1)); - matrixBuf.put(2 * 4 + 0, side.get(2)); - - matrixBuf.put(0 * 4 + 1, up.get(0)); - matrixBuf.put(1 * 4 + 1, up.get(1)); - matrixBuf.put(2 * 4 + 1, up.get(2)); - - matrixBuf.put(0 * 4 + 2, -forward.get(0)); - matrixBuf.put(1 * 4 + 2, -forward.get(1)); - matrixBuf.put(2 * 4 + 2, -forward.get(2)); - - gl.glMultMatrixf(matrixBuf); - gl.glTranslatef(-eyex, -eyey, -eyez); + public void gluLookAt(final GLMatrixFunc gl, + 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) { + 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); } /** - * Method gluProject - * + * Map object coordinates to window coordinates. + * <p> + * Traditional <code>gluProject</code> implementation. + * </p> + * * @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 ) { + 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); + } - float[] in = this.in; - float[] out = this.out; + /** + * Map object coordinates to window coordinates. + */ + @SuppressWarnings("deprecation") + public boolean gluProject(final float objx, final float objy, final float objz, + final FloatBuffer modelMatrix, + final FloatBuffer projMatrix, + final int[] viewport, final int viewport_offset, + final float[] win_pos, final int win_pos_offset ) { + 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, modelMatrix_offset, in, 0, out); - FloatUtil.multMatrixVecf(projMatrix, projMatrix_offset, out, 0, in); + FloatUtil.multMatrixVec(modelMatrix, in, out); + FloatUtil.multMatrixVec(projMatrix, out, in); if (in[3] == 0.0f) { return false; @@ -506,45 +271,9 @@ public class ProjectFloat { return true; } - public boolean gluProject(float objx, float objy, float objz, - FloatBuffer modelMatrix, - FloatBuffer projMatrix, - int[] viewport, int viewport_offset, - float[] win_pos, int win_pos_offset ) { - - FloatBuffer in = this.inBuf; - FloatBuffer out = this.outBuf; - - in.put(0, objx); - in.put(1, objy); - in.put(2, objz); - in.put(3, 1.0f); - - FloatUtil.multMatrixVecf(modelMatrix, in, out); - FloatUtil.multMatrixVecf(projMatrix, out, in); - - if (in.get(3) == 0.0f) { - return false; - } - - in.put(3, (1.0f / in.get(3)) * 0.5f); - - // Map x, y and z to range 0-1 - in.put(0, in.get(0) * in.get(3) + 0.5f); - in.put(1, in.get(1) * in.get(3) + 0.5f); - in.put(2, in.get(2) * in.get(3) + 0.5f); - - // Map x,y to viewport - win_pos[0+win_pos_offset] = in.get(0) * viewport[2+viewport_offset] + viewport[0+viewport_offset]; - win_pos[1+win_pos_offset] = in.get(1) * viewport[3+viewport_offset] + viewport[1+viewport_offset]; - win_pos[2+win_pos_offset] = in.get(2); - - return true; - } - /** - * Method gluProject - * + * Map object coordinates to window coordinates. + * * @param objx * @param objy * @param objz @@ -552,151 +281,140 @@ public class ProjectFloat { * @param projMatrix * @param viewport * @param win_pos - * + * * @return */ - public boolean gluProject(float objx, float objy, float objz, - FloatBuffer modelMatrix, - FloatBuffer projMatrix, - IntBuffer viewport, - FloatBuffer win_pos) { + @SuppressWarnings("deprecation") + public boolean gluProject(final float objx, final float objy, final float objz, + final FloatBuffer modelMatrix, + final FloatBuffer projMatrix, + final IntBuffer viewport, + final FloatBuffer win_pos) { - FloatBuffer in = this.inBuf; - FloatBuffer out = this.outBuf; + final float[] in = this.mat4Tmp1; + final float[] out = this.mat4Tmp2; - in.put(0, objx); - in.put(1, objy); - in.put(2, objz); - in.put(3, 1.0f); + 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.get(3) == 0.0f) { + if (in[3] == 0.0f) { return false; } - in.put(3, (1.0f / in.get(3)) * 0.5f); + in[3] = (1.0f / in[3]) * 0.5f; // Map x, y and z to range 0-1 - in.put(0, in.get(0) * in.get(3) + 0.5f); - in.put(1, in.get(1) * in.get(3) + 0.5f); - in.put(2, in.get(2) * in.get(3) + 0.5f); + 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 - int vPos = viewport.position(); - int wPos = win_pos.position(); - win_pos.put(0+wPos, in.get(0) * viewport.get(2+vPos) + viewport.get(0+vPos)); - win_pos.put(1+wPos, in.get(1) * viewport.get(3+vPos) + viewport.get(1+vPos)); - win_pos.put(2+wPos, in.get(2)); + final int vPos = viewport.position(); + final int wPos = win_pos.position(); + win_pos.put(0+wPos, in[0] * viewport.get(2+vPos) + viewport.get(0+vPos)); + win_pos.put(1+wPos, in[1] * viewport.get(3+vPos) + viewport.get(1+vPos)); + win_pos.put(2+wPos, in[2]); return true; } /** - * Method gluUnproject - * + * Map window coordinates to object coordinates. + * <p> + * Traditional <code>gluUnProject</code> implementation. + * </p> + * + * @param winx + * @param winy + * @param winz + * @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(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) { + return FloatUtil.mapWinToObjCoords(winx, winy, winz, + modelMatrix, modelMatrix_offset, + projMatrix, projMatrix_offset, + viewport, viewport_offset, + obj_pos, obj_pos_offset, + mat4Tmp1, mat4Tmp2); + } + + + /** + * Map window coordinates to object coordinates. + * * @param winx * @param winy * @param winz * @param modelMatrix * @param projMatrix * @param viewport + * @param viewport_offset * @param obj_pos - * - * @return + * @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, - float[] modelMatrix, int modelMatrix_offset, - float[] projMatrix, int projMatrix_offset, - int[] viewport, int viewport_offset, - float[] obj_pos, int obj_pos_offset) { - float[] in = this.in; - float[] out = this.out; - - FloatUtil.multMatrixf(projMatrix, projMatrix_offset, modelMatrix, modelMatrix_offset, matrix, 0); - - if (!gluInvertMatrixf(matrix, 0, matrix, 0)) { + @SuppressWarnings("deprecation") + 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, mat4Tmp1) ) { 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(matrix, 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; } - - 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) { - FloatBuffer in = this.inBuf; - FloatBuffer out = this.outBuf; - - FloatUtil.multMatrixf(projMatrix, modelMatrix, matrixBuf); - - if (!gluInvertMatrixf(matrixBuf, matrixBuf)) { - return false; - } - - in.put(0, winx); - in.put(1, winy); - in.put(2, winz); - in.put(3, 1.0f); - - // Map x and y from window coordinates - in.put(0, (in.get(0) - viewport[0+viewport_offset]) / viewport[2+viewport_offset]); - in.put(1, (in.get(1) - viewport[1+viewport_offset]) / viewport[3+viewport_offset]); - - // Map to range -1 to 1 - in.put(0, in.get(0) * 2 - 1); - in.put(1, in.get(1) * 2 - 1); - in.put(2, in.get(2) * 2 - 1); - - FloatUtil.multMatrixVecf(matrixBuf, in, out); - - if (out.get(3) == 0.0f) { - return false; - } - - out.put(3, 1.0f / out.get(3)); - - obj_pos[0+obj_pos_offset] = out.get(0) * out.get(3); - obj_pos[1+obj_pos_offset] = out.get(1) * out.get(3); - obj_pos[2+obj_pos_offset] = out.get(2) * out.get(3); - - return true; - } - /** - * Method gluUnproject - * + * Map window coordinates to object coordinates. + * * @param winx * @param winy * @param winz @@ -704,123 +422,98 @@ public class ProjectFloat { * @param projMatrix * @param viewport * @param obj_pos - * - * @return + * + * @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, - IntBuffer viewport, - FloatBuffer obj_pos) { - FloatBuffer in = this.inBuf; - FloatBuffer out = this.outBuf; - - FloatUtil.multMatrixf(projMatrix, modelMatrix, matrixBuf); - - if (!gluInvertMatrixf(matrixBuf, matrixBuf)) { + @SuppressWarnings("deprecation") + public boolean gluUnProject(final float winx, final float winy, final float winz, + final FloatBuffer modelMatrix, + final FloatBuffer projMatrix, + final IntBuffer viewport, + final FloatBuffer obj_pos) { + final int vPos = viewport.position(); + final int oPos = obj_pos.position(); + + // mat4Tmp1 = P x M + FloatUtil.multMatrix(projMatrix, modelMatrix, mat4Tmp1); + + // mat4Tmp1 = Inv(P x M) + if ( null == FloatUtil.invertMatrix(mat4Tmp1, mat4Tmp1) ) { return false; } - in.put(0, winx); - in.put(1, winy); - in.put(2, winz); - in.put(3, 1.0f); + mat4Tmp2[0] = winx; + mat4Tmp2[1] = winy; + mat4Tmp2[2] = winz; + mat4Tmp2[3] = 1.0f; // Map x and y from window coordinates - int vPos = viewport.position(); - int oPos = obj_pos.position(); - in.put(0, (in.get(0) - viewport.get(0+vPos)) / viewport.get(2+vPos)); - in.put(1, (in.get(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.put(0, in.get(0) * 2 - 1); - in.put(1, in.get(1) * 2 - 1); - in.put(2, in.get(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.get(3) == 0.0f) { + if (mat4Tmp2[3+raw_off] == 0.0) { return false; } - out.put(3, 1.0f / out.get(3)); + mat4Tmp2[3+raw_off] = 1.0f / mat4Tmp2[3+raw_off]; - obj_pos.put(0+oPos, out.get(0) * out.get(3)); - obj_pos.put(1+oPos, out.get(1) * out.get(3)); - obj_pos.put(2+oPos, out.get(2) * out.get(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; } /** - * Method gluUnproject4 - * + * Map window coordinates to object coordinates. + * <p> + * Traditional <code>gluUnProject4</code> implementation. + * </p> + * * @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 + * @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 ) { - float[] in = this.in; - 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); } /** - * Method gluUnproject4 - * + * Map window coordinates to object coordinates. + * * @param winx * @param winy * @param winz @@ -831,78 +524,75 @@ public class ProjectFloat { * @param near * @param far * @param obj_pos - * - * @return + * + * @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) { - FloatBuffer in = this.inBuf; - FloatBuffer out = this.outBuf; - - FloatUtil.multMatrixf(projMatrix, modelMatrix, matrixBuf); - - if (!gluInvertMatrixf(matrixBuf, matrixBuf)) + @SuppressWarnings("deprecation") + 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, mat4Tmp1) ) { return false; + } - in.put(0, winx); - in.put(1, winy); - in.put(2, winz); - in.put(3, clipw); + mat4Tmp2[0] = winx; + mat4Tmp2[1] = winy; + mat4Tmp2[2] = winz; + mat4Tmp2[3] = clipw; // Map x and y from window coordinates - int vPos = viewport.position(); - in.put(0, (in.get(0) - viewport.get(0+vPos)) / viewport.get(2+vPos)); - in.put(1, (in.get(1) - viewport.get(1+vPos)) / viewport.get(3+vPos)); - in.put(2, (in.get(2) - near) / (far - near)); + final int vPos = viewport.position(); + 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.put(0, in.get(0) * 2 - 1); - in.put(1, in.get(1) * 2 - 1); - in.put(2, in.get(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.get(3) == 0.0f) + if (mat4Tmp2[3+raw_off] == 0.0f) { return false; + } - int oPos = obj_pos.position(); - obj_pos.put(0+oPos, out.get(0)); - obj_pos.put(1+oPos, out.get(1)); - obj_pos.put(2+oPos, out.get(2)); - obj_pos.put(3+oPos, out.get(3)); + final int oPos = obj_pos.position(); + 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 <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 + * @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, + final float deltaX, final float deltaY, + final IntBuffer viewport) { if (deltaX <= 0 || deltaY <= 0) { return; } /* Translate and scale the picked region to the entire window */ - int vPos = viewport.position(); + final int vPos = viewport.position(); gl.glTranslatef((viewport.get(2+vPos) - 2 * (x - viewport.get(0+vPos))) / deltaX, (viewport.get(3+vPos) - 2 * (y - viewport.get(1+vPos))) / deltaY, 0); @@ -910,31 +600,24 @@ public class ProjectFloat { } /** - * Method gluPickMatrix - * + * 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 + * @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); } } |