diff options
author | Sven Gothel <[email protected]> | 2014-07-03 09:35:34 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-07-03 09:35:34 +0200 |
commit | d44e8ada30d62149c5d4d4b8fdba7cc33f8c765b (patch) | |
tree | b05fbfb142497d7d62760d8d908236c5f7280fe5 /src/jogl | |
parent | 36327e24cf586b50bf18e87d7d13d53eb41cf1d9 (diff) |
Bug 1021: Refine Stereo Rendering API and OculusVR implementing renderer
Refine API in regards to proper package names, interface
and high-level access to eye specific constant parameter
and variable eye movement.
+++
Commit 36327e24cf586b50bf18e87d7d13d53eb41cf1d9 introduced 'GLEventListener2'
Move javax.media.opengl.GLEventListener2
-> com.jogamp.opengl.util.CustomRendererListener
-> com.jogamp.opengl.util.stereo.StereoRendererListener
StereoRendererListener adds stereoscopic specific:
public void reshapeEye(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height,
final EyeParameter eyeParam, final EyePose eyePose);
.. see below.
++
Add com.jogamp.opengl.util.stereo:
- EyeParameter (Constant eye parameters, like IPD and FOV)
- EyePose (Current eye position and orientation)
+++
Add com.jogamp.opengl.math.FovHVHalves to support
non-centered bi-directional FOV for lenses.
Add respective FloatUtil.makePerspective(.. FovHVHalves fovhv ) variant.
+++
Diffstat (limited to 'src/jogl')
-rw-r--r-- | src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java | 98 | ||||
-rw-r--r-- | src/jogl/classes/com/jogamp/opengl/math/FovHVHalves.java | 90 | ||||
-rw-r--r-- | src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java | 24 | ||||
-rw-r--r-- | src/jogl/classes/com/jogamp/opengl/util/CustomRendererListener.java (renamed from src/jogl/classes/javax/media/opengl/GLEventListener2.java) | 21 | ||||
-rw-r--r-- | src/jogl/classes/com/jogamp/opengl/util/stereo/EyeParameter.java | 68 | ||||
-rw-r--r-- | src/jogl/classes/com/jogamp/opengl/util/stereo/EyePose.java | 69 | ||||
-rw-r--r-- | src/jogl/classes/com/jogamp/opengl/util/stereo/StereoRendererListener.java | 73 |
7 files changed, 402 insertions, 41 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java b/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java index f5200443c..eeedf531c 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java +++ b/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java @@ -548,7 +548,8 @@ public final class FloatUtil { } /** - * Make given matrix the perspective matrix based on given parameters. + * Make given matrix the perspective {@link #makeFrustum(float[], int, boolean, float, float, float, float, float, float) frustum} + * matrix based on given parameters. * <p> * All matrix fields are only set if <code>initM</code> is <code>true</code>. * </p> @@ -556,7 +557,7 @@ public final class FloatUtil { * @param m 4x4 matrix in column-major order (also result) * @param m_offset offset in given array <i>m</i>, i.e. start of the 4x4 matrix * @param initM if true, given matrix will be initialized w/ identity matrix, - * otherwise only the non-zero fields are set. + * otherwise only the frustum fields are set. * @param fovy angle in radians * @param aspect * @param zNear @@ -565,14 +566,81 @@ public final class FloatUtil { */ public static float[] makePerspective(final float[] m, final int m_off, final boolean initM, final float fovy, final float aspect, final float zNear, final float zFar) { - float top=(float)Math.tan(fovy)*zNear; - float bottom=-1.0f*top; - float left=aspect*bottom; - float right=aspect*top; + final float top=(float)Math.tan(fovy)*zNear; + final float bottom=-1.0f*top; + final float left=aspect*bottom; + final float right=aspect*top; return makeFrustum(m, m_off, initM, left, right, bottom, top, zNear, zFar); } /** + * Make given matrix the perspective {@link #makeFrustum(float[], int, boolean, float, float, float, float, float, float) frustum} + * matrix based on given parameters. + * <p> + * All matrix fields are only set if <code>initM</code> is <code>true</code>. + * </p> + * + * @param m 4x4 matrix in column-major order (also result) + * @param m_offset offset in given array <i>m</i>, i.e. start of the 4x4 matrix + * @param initM if true, given matrix will be initialized w/ identity matrix, + * otherwise only the frustum fields are set. + * @param fovhv {@link FovHVHalves} field of view in both directions, may not be centered, either in radians or tangent + * @param zNear + * @param zFar + * @return given matrix for chaining + */ + public static float[] makePerspective(final float[] m, final int m_offset, final boolean initM, + final FovHVHalves fovhv, final float zNear, final float zFar) { + if( initM ) { + // m[m_offset+0+4*0] = 1f; + m[m_offset+1+4*0] = 0f; + m[m_offset+2+4*0] = 0f; + m[m_offset+3+4*0] = 0f; + + m[m_offset+0+4*1] = 0f; + // m[m_offset+1+4*1] = 1f; + m[m_offset+2+4*1] = 0f; + m[m_offset+3+4*1] = 0f; + + // m[m_offset+0+4*2] = 0f; + // m[m_offset+1+4*2] = 0f; + // m[m_offset+2+4*2] = 1f; + // m[m_offset+3+4*2] = 0f; + + m[m_offset+0+4*3] = 0f; + m[m_offset+1+4*3] = 0f; + // m[m_offset+2+4*3] = 0f; + // m[m_offset+3+4*3] = 1f; + } + + final float projScaleX = 2.0f / ( fovhv.left + fovhv.right ); + final float projScaleY = 2.0f / ( fovhv.top + fovhv.bottom ); + final float projOffsetX = ( fovhv.left - fovhv.right ) * projScaleX * 0.5f; + final float projOffsetY = -1f * ( fovhv.top - fovhv.bottom ) * projScaleY * 0.5f; + + // Produces X result, mapping clip edges to [-w,+w] + m[m_offset+0+4*0] = projScaleX; + m[m_offset+0+4*2] = -1f * projOffsetX; + + // Produces Y result, mapping clip edges to [-w,+w] (Y=up) + m[m_offset+1+4*1] = projScaleY; + m[m_offset+1+4*2] = -1f * projOffsetY; + + // Custom Z-buffer result .. same as frustum matrix! + m[m_offset+2+4*2] = -1.0f*(zFar+zNear)/(zFar-zNear); + m[m_offset+2+4*3] = -2.0f*(zFar*zNear)/(zFar-zNear); + // alternative: + // m[m_offset+2+4*2] = -1.0f * zFar / (zNear - zFar); + // m[m_offset+2+4*3] = (zFar * zNear) / (zNear - zFar); + + // Produces W result (= Z in) + m[m_offset+3+4*2] = -1.0f; + m[m_offset+3+4*3] = 0f; + + return m; + } + + /** * Make given matrix the <i>look-at</i> matrix based on given parameters. * <p> * Consist out of two matrix multiplications: @@ -1034,7 +1102,7 @@ public final class FloatUtil { final float[] modelMatrix, final int modelMatrix_offset, final float[] projMatrix, final int projMatrix_offset, final int[] viewport, final int viewport_offset, - final float[] win_pos, int win_pos_offset, + final float[] win_pos, final int win_pos_offset, final float[/*4*/] vec4Tmp1, final float[/*4*/] vec4Tmp2) { vec4Tmp1[0] = objx; vec4Tmp1[1] = objy; @@ -1088,7 +1156,7 @@ public final class FloatUtil { public static boolean mapObjToWinCoords(final float objx, final float objy, final float objz, final float[/*16*/] mat4PMv, final int[] viewport, final int viewport_offset, - final float[] win_pos, int win_pos_offset, + final float[] win_pos, final int win_pos_offset, final float[/*4*/] vec4Tmp1, final float[/*4*/] vec4Tmp2) { vec4Tmp2[0] = objx; vec4Tmp2[1] = objy; @@ -1338,11 +1406,11 @@ public final class FloatUtil { * @return true if successful, otherwise false (failed to invert matrix, or becomes infinity due to zero z) */ public static boolean mapWinToObjCoords(final float winx, final float winy, final float winz, final float clipw, - float[] modelMatrix, int modelMatrix_offset, - float[] projMatrix, int projMatrix_offset, - int[] viewport, int viewport_offset, - float near, float far, - float[] obj_pos, int obj_pos_offset, + final float[] modelMatrix, final int modelMatrix_offset, + final float[] projMatrix, final int projMatrix_offset, + final int[] viewport, final int viewport_offset, + final float near, final float far, + final float[] obj_pos, final int obj_pos_offset, final float[/*16*/] mat4Tmp1, final float[/*16*/] mat4Tmp2) { // mat4Tmp1 = P x Mv multMatrix(projMatrix, projMatrix_offset, modelMatrix, modelMatrix_offset, mat4Tmp1, 0); @@ -1445,7 +1513,7 @@ public final class FloatUtil { * @param d result a*b in column-major order * @return given result matrix <i>d</i> for chaining */ - public static float[] multMatrix(final float[] a, final int a_off, final float[] b, final int b_off, float[] d, final int d_off) { + public static float[] multMatrix(final float[] a, final int a_off, final float[] b, final int b_off, final float[] d, final int d_off) { final float b00 = b[b_off+0+0*4]; final float b10 = b[b_off+1+0*4]; final float b20 = b[b_off+2+0*4]; @@ -1509,7 +1577,7 @@ public final class FloatUtil { * @param d result a*b in column-major order * @return given result matrix <i>d</i> for chaining */ - public static float[] multMatrix(final float[] a, final float[] b, float[] d) { + public static float[] multMatrix(final float[] a, final float[] b, final float[] d) { final float b00 = b[0+0*4]; final float b10 = b[1+0*4]; final float b20 = b[2+0*4]; diff --git a/src/jogl/classes/com/jogamp/opengl/math/FovHVHalves.java b/src/jogl/classes/com/jogamp/opengl/math/FovHVHalves.java new file mode 100644 index 000000000..18bba8c45 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/math/FovHVHalves.java @@ -0,0 +1,90 @@ +/** + * Copyright 2014 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.opengl.math; + +/** + * Horizontal and vertical field of view (FOV) halves, + * allowing a non-centered projection. + * <p> + * The values might be either in tangent or radians. + * </p> + */ +public final class FovHVHalves { + /** Half horizontal FOV from center to left. */ + public final float left; + /** Half horizontal FOV from center to right. */ + public final float right; + /** Half vertical FOV from center to top. */ + public final float top; + /** Half vertical FOV from center to bottom. */ + public final float bottom; + /** If true, values are in tangent, otherwise radians.*/ + public final boolean inTangents; + + /** + * Constructor for one {@link FovHVHalves} instance. + * + * @param left half horizontal FOV, left side, in tangent or radians + * @param right half horizontal FOV, right side, in tangent or radians + * @param top half vertical FOV, top side, in tangent or radians + * @param bottom half vertical FOV, bottom side, in tangent or radians + * @param inTangents if true, values are in tangent, otherwise radians + */ + public FovHVHalves(final float left, final float right, final float top, final float bottom, final boolean inTangents) { + this.left = left; + this.right = right; + this.top = top; + this.bottom = bottom; + this.inTangents = inTangents; + } + + /** + * Returns a symmetrical centered {@link FovHVHalves} instance in tangents, using: + * <pre> + final float halfHorizFovTan = (float)Math.tan(horizontalFov/2f); + final float halfVertFovTan = (float)Math.tan(verticalFov/2f); + * </pre> + * @param horizontalFov whole horizontal FOV in radians + * @param verticalFov whole vertical FOV in radians + */ + public static FovHVHalves createByRadians(final float horizontalFov, final float verticalFov) { + final float halfHorizFovTan = (float)Math.tan(horizontalFov/2f); + final float halfVertFovTan = (float)Math.tan(verticalFov/2f); + return new FovHVHalves(halfHorizFovTan, halfHorizFovTan, halfVertFovTan, halfVertFovTan, true); + } + + /** Returns the full horizontal FOV, i.e. {@link #left} + {@link #right}. */ + public final float horzFov() { return left+right; } + + /** Returns the full vertical FOV, i.e. {@link #top} + {@link #bottom}. */ + public final float vertFov() { return top+bottom; } + + public final String toString() { + return "FovHVHalves["+(inTangents?"tangents":"radians")+": "+left+" l, "+right+" r, "+top+" t, "+bottom+" b]"; + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java b/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java index 607d8ef9d..c11c2bd2b 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java +++ b/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java @@ -33,13 +33,17 @@ public final class VectorUtil { public static final float[] VEC3_ONE = { 1f, 1f, 1f }; public static final float[] VEC3_ZERO = { 0f, 0f, 0f }; + public static final float[] VEC3_UNIT_Y = { 0f, 1f, 0f }; + public static final float[] VEC3_UNIT_Y_NEG = { 0f, -1f, 0f }; + public static final float[] VEC3_UNIT_Z = { 0f, 0f, 1f }; + public static final float[] VEC3_UNIT_Z_NEG = { 0f, 0f, -1f }; public enum Winding { CW(-1), CCW(1); public final int dir; - Winding(int dir) { + Winding(final int dir) { this.dir = dir; } } @@ -52,7 +56,7 @@ public final class VectorUtil { * @param srcOffset offset of src in array * @return copied output vector for chaining */ - public static float[] copyVec2(final float[] dst, int dstOffset, final float[] src, int srcOffset) + public static float[] copyVec2(final float[] dst, final int dstOffset, final float[] src, final int srcOffset) { System.arraycopy(src, srcOffset, dst, dstOffset, 2); return dst; @@ -66,7 +70,7 @@ public final class VectorUtil { * @param srcOffset offset of src in array * @return copied output vector for chaining */ - public static float[] copyVec3(final float[] dst, int dstOffset, final float[] src, int srcOffset) + public static float[] copyVec3(final float[] dst, final int dstOffset, final float[] src, final int srcOffset) { System.arraycopy(src, srcOffset, dst, dstOffset, 3); return dst; @@ -80,7 +84,7 @@ public final class VectorUtil { * @param srcOffset offset of src in array * @return copied output vector for chaining */ - public static float[] copyVec4(final float[] dst, int dstOffset, final float[] src, int srcOffset) + public static float[] copyVec4(final float[] dst, final int dstOffset, final float[] src, final int srcOffset) { System.arraycopy(src, srcOffset, dst, dstOffset, 4); return dst; @@ -92,7 +96,7 @@ public final class VectorUtil { * Implementation uses {@link FloatUtil#isEqual(float, float)}, see API doc for details. * </p> */ - public static boolean isVec2Equal(final float[] vec1, int vec1Offset, final float[] vec2, int vec2Offset) { + public static boolean isVec2Equal(final float[] vec1, final int vec1Offset, final float[] vec2, final int vec2Offset) { return FloatUtil.isEqual(vec1[0+vec1Offset], vec2[0+vec2Offset]) && FloatUtil.isEqual(vec1[1+vec1Offset], vec2[1+vec2Offset]) ; } @@ -103,7 +107,7 @@ public final class VectorUtil { * Implementation uses {@link FloatUtil#isEqual(float, float)}, see API doc for details. * </p> */ - public static boolean isVec3Equal(final float[] vec1, int vec1Offset, final float[] vec2, int vec2Offset) { + public static boolean isVec3Equal(final float[] vec1, final int vec1Offset, final float[] vec2, final int vec2Offset) { return FloatUtil.isEqual(vec1[0+vec1Offset], vec2[0+vec2Offset]) && FloatUtil.isEqual(vec1[1+vec1Offset], vec2[1+vec2Offset]) && FloatUtil.isEqual(vec1[2+vec1Offset], vec2[2+vec2Offset]) ; @@ -115,7 +119,7 @@ public final class VectorUtil { * Implementation uses {@link FloatUtil#isEqual(float, float, float)}, see API doc for details. * </p> */ - public static boolean isVec2Equal(final float[] vec1, int vec1Offset, final float[] vec2, int vec2Offset, final float epsilon) { + public static boolean isVec2Equal(final float[] vec1, final int vec1Offset, final float[] vec2, final int vec2Offset, final float epsilon) { return FloatUtil.isEqual(vec1[0+vec1Offset], vec2[0+vec2Offset], epsilon) && FloatUtil.isEqual(vec1[1+vec1Offset], vec2[1+vec2Offset], epsilon) ; } @@ -126,7 +130,7 @@ public final class VectorUtil { * Implementation uses {@link FloatUtil#isEqual(float, float, float)}, see API doc for details. * </p> */ - public static boolean isVec3Equal(final float[] vec1, int vec1Offset, final float[] vec2, int vec2Offset, final float epsilon) { + public static boolean isVec3Equal(final float[] vec1, final int vec1Offset, final float[] vec2, final int vec2Offset, final float epsilon) { return FloatUtil.isEqual(vec1[0+vec1Offset], vec2[0+vec2Offset], epsilon) && FloatUtil.isEqual(vec1[1+vec1Offset], vec2[1+vec2Offset], epsilon) && FloatUtil.isEqual(vec1[2+vec1Offset], vec2[2+vec2Offset], epsilon) ; @@ -250,7 +254,7 @@ public final class VectorUtil { */ public static float normSquareVec2(final float[] vec, final int offset) { float v = vec[0+offset]; - float r = v*v; + final float r = v*v; v = vec[1+offset]; return r + v*v; } @@ -956,7 +960,7 @@ public final class VectorUtil { * @param epsilon * @return resulting intersecting if exists, otherwise null */ - public static float[] line2PlaneIntersection(final float[] result, final Ray ray, float[/*4*/] plane, final float epsilon) { + public static float[] line2PlaneIntersection(final float[] result, final Ray ray, final float[/*4*/] plane, final float epsilon) { final float tmp = dotVec3(ray.dir, plane) ; if ( Math.abs(tmp) < epsilon ) { diff --git a/src/jogl/classes/javax/media/opengl/GLEventListener2.java b/src/jogl/classes/com/jogamp/opengl/util/CustomRendererListener.java index d4e8e84a4..0e6de5178 100644 --- a/src/jogl/classes/javax/media/opengl/GLEventListener2.java +++ b/src/jogl/classes/com/jogamp/opengl/util/CustomRendererListener.java @@ -25,13 +25,16 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ -package javax.media.opengl; +package com.jogamp.opengl.util; + +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLEventListener; /** * Extended {@link GLEventListener} interface * supporting more fine grained control over the implementation. */ -public interface GLEventListener2 extends GLEventListener { +public interface CustomRendererListener extends GLEventListener { /** * {@link #display(GLAutoDrawable, int) display flag}: Repeat last produced image. * <p> @@ -57,18 +60,4 @@ public interface GLEventListener2 extends GLEventListener { * @param flags */ public void display(final GLAutoDrawable drawable, final int flags); - - /** - * Might be called instead of {@link #reshape(GLAutoDrawable, int, int, int, int) reshape} - * to specify a custom projection and modelview matrix determined by the caller. - * <p> - * Method is usually called by a custom rendering loop, - * e.g. for manual stereo rendering or the like. - * </p> - * - * @param drawable the triggering {@link GLAutoDrawable} - * @param mat4Projection float[16] projection matrix - * @param mat4Modelview float[16] modelview matrix - */ - public void setProjectionModelview(final GLAutoDrawable drawable, final float[] mat4Projection, final float[] mat4Modelview); } diff --git a/src/jogl/classes/com/jogamp/opengl/util/stereo/EyeParameter.java b/src/jogl/classes/com/jogamp/opengl/util/stereo/EyeParameter.java new file mode 100644 index 000000000..7774d67e2 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/util/stereo/EyeParameter.java @@ -0,0 +1,68 @@ +/** + * Copyright 2014 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.opengl.util.stereo; + +import com.jogamp.opengl.math.FovHVHalves; + +/** + * Constant parameter for one eye. + */ +public final class EyeParameter { + /** Eye number, <code>0</code> for the left eye and <code>1</code> for the right eye. */ + public final int number; + + /** float[3] eye position vector used to define eye height in meter relative to <i>actor</i>. */ + public final float[] positionOffset; + + /** Field of view in both directions, may not be centered, either in radians or tangent. */ + public final FovHVHalves fovhv; + + /** IPD related horizontal distance from nose to pupil in meter. */ + public final float distNoseToPupilX; + + /** Vertical distance from middle-line to pupil in meter. */ + public final float distMiddleToPupilY; + + /** Z-axis eye relief in meter. */ + public final float eyeReliefZ; + + public EyeParameter(final int number, final float[] positionOffset, final FovHVHalves fovhv, + final float distNoseToPupil, final float verticalDelta, final float eyeRelief) { + this.number = number; + this.positionOffset = new float[3]; + System.arraycopy(positionOffset, 0, this.positionOffset, 0, 3); + this.fovhv = fovhv; + this.distNoseToPupilX = distNoseToPupil; + this.distMiddleToPupilY = verticalDelta; + this.eyeReliefZ = eyeRelief; + } + public final String toString() { + return "EyeParam[num"+number+", posOff["+positionOffset[0]+", "+positionOffset[1]+", "+positionOffset[2]+"], "+fovhv+ + ", distPupil[noseX "+distNoseToPupilX+", middleY "+distMiddleToPupilY+", reliefZ "+eyeReliefZ+"]]"; + } +}
\ No newline at end of file diff --git a/src/jogl/classes/com/jogamp/opengl/util/stereo/EyePose.java b/src/jogl/classes/com/jogamp/opengl/util/stereo/EyePose.java new file mode 100644 index 000000000..2690097f1 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/util/stereo/EyePose.java @@ -0,0 +1,69 @@ +/** + * Copyright 2014 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.opengl.util.stereo; + +import com.jogamp.opengl.math.Quaternion; + +/** + * Position and orientation of one eye. + */ +public final class EyePose { + /** Eye number, <code>0</code> for the left eye and <code>1</code> for the right eye. */ + public final int number; + + /** float[3] eye position vector. */ + public final float[] position; + + /** Eye orientation */ + public final Quaternion orientation; + + public EyePose(final int number) { + this.number = number; + this.position = new float[3]; + this.orientation = new Quaternion(); + } + public EyePose(final int number, final float[] position, final Quaternion orientation) { + this(number); + set(position, orientation); + } + + /** Set position and orientation of this instance. */ + public final void set(final float[] position, final Quaternion orientation) { + System.arraycopy(position, 0, this.position, 0, 3); + this.orientation.set(orientation); + } + /** Set position and orientation of this instance. */ + public final void setPosition(final float posX, final float posY, final float posZ) { + position[0] = posX; + position[1] = posY; + position[2] = posZ; + } + public final String toString() { + return "EyePose[num"+number+", pos["+position[0]+", "+position[1]+", "+position[2]+"], "+orientation+"]"; + } +}
\ No newline at end of file diff --git a/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoRendererListener.java b/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoRendererListener.java new file mode 100644 index 000000000..5e6e40a08 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoRendererListener.java @@ -0,0 +1,73 @@ +/** + * Copyright 2014 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.opengl.util.stereo; + +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLEventListener; + +import com.jogamp.opengl.math.FloatUtil; +import com.jogamp.opengl.util.CustomRendererListener; + +/** + * Extended {@link GLEventListener} and {@link CustomRendererListener} interface + * supporting stereoscopic client rendering. + */ +public interface StereoRendererListener extends CustomRendererListener { + /** + * Stereo capable specialization of {@link #reshape(GLAutoDrawable, int, int, int, int)}. + * <p> + * Called by the stereo renderer before each {@link #display(GLAutoDrawable)} + * or {@link #display(GLAutoDrawable, int)} call. + * </p> + * <p> + * The client can update it's viewport associated data + * and view volume of the window appropriately. + * </p> + * <p> + * The client shall also update it's projection- and modelview matrices according + * to the given {@link EyeParameter} and {@link EyePose}. + * </p> + * <p> + * For efficiency the GL viewport has already been updated + * via <code>glViewport(x, y, width, height)</code> when this method is called. + * </p> + * + * @param drawable the triggering {@link GLAutoDrawable} + * @param x viewport x-coord in pixel units + * @param y viewport y-coord in pixel units + * @param width viewport width in pixel units + * @param height viewport height in pixel units + * @param eyeParam constant eye parameter, i.e. FOV and IPD + * @param eyePose current eye position and orientation + * @see FloatUtil#makePerspective(float[], int, boolean, com.jogamp.opengl.math.FloatUtil.FovHVHalves, float, float) + */ + public void reshapeEye(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height, + final EyeParameter eyeParam, final EyePose eyePose); + + +} |