JOGL v2.6.0-rc-20250712
JOGL, High-Performance Graphics Binding for Java™ (public API).
StereoUtil.java
Go to the documentation of this file.
1/**
2 * Copyright 2014-2023 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28package com.jogamp.opengl.util.stereo;
29
30import com.jogamp.math.Matrix4f;
31import com.jogamp.math.Quaternion;
32import com.jogamp.math.Vec3f;
33import com.jogamp.opengl.util.CustomGLEventListener;
34import com.jogamp.opengl.util.stereo.StereoDeviceRenderer.Eye;
35
36public class StereoUtil {
37 /**
38 * Return the vertical pupil center from the screen top in the range [0..1].
39 * @param screenHeightInMeters
40 * @param pupilCenterFromScreenTopInMeters
41 */
42 public static float getVertPupilCenterFromTop(final float screenHeightInMeters, final float pupilCenterFromScreenTopInMeters) {
43 return pupilCenterFromScreenTopInMeters / screenHeightInMeters;
44 }
45
46 /**
47 * Return the horizontal pupil center from the left side for both eyes in the range [0..1].
48 * <pre>
49 <-------------left eye------------->| |<-----------right eye-------------->
50 <------------------------------------screenSizeInMeters.Width----------------------------------->
51 <------interpupillaryDistanceInMeters------>
52 <--centerFromLeftInMeters->
53 ^
54 center of pupil
55 * </pre>
56 *
57 * @param screenWidthInMeters
58 * @param interpupillaryDistanceInMeters
59 */
60 public static float[] getHorizPupilCenterFromLeft(final float screenWidthInMeters, final float interpupillaryDistanceInMeters) {
61 final float visibleWidthOfOneEye = 0.5f * screenWidthInMeters;
62 final float leftPupilCenterFromLeftInMeters = ( screenWidthInMeters - interpupillaryDistanceInMeters ) * 0.5f;
63 final float rightPupilCenterFromMiddleInMeters = leftPupilCenterFromLeftInMeters + interpupillaryDistanceInMeters - visibleWidthOfOneEye;
64 return new float[] { leftPupilCenterFromLeftInMeters / visibleWidthOfOneEye,
65 rightPupilCenterFromMiddleInMeters / visibleWidthOfOneEye };
66 }
67
68 /** See {@link StereoDeviceRenderer#getDistortionBits()}. */
69 public static boolean usesBarrelDistortion(final int distortionBits) { return 0 != ( distortionBits & StereoDeviceRenderer.DISTORTION_BARREL ) ; }
70 /** See {@link StereoDeviceRenderer#getDistortionBits()}. */
71 public static boolean usesTimewarpDistortion(final int distortionBits) { return 0 != ( distortionBits & StereoDeviceRenderer.DISTORTION_TIMEWARP ) ; }
72 /** See {@link StereoDeviceRenderer#getDistortionBits()}. */
73 public static boolean usesChromaticDistortion(final int distortionBits) { return 0 != ( distortionBits & StereoDeviceRenderer.DISTORTION_CHROMATIC ) ; }
74 /** See {@link StereoDeviceRenderer#getDistortionBits()}. */
75 public static boolean usesVignetteDistortion(final int distortionBits) { return 0 != ( distortionBits & StereoDeviceRenderer.DISTORTION_VIGNETTE ) ; }
76
77 /** See {@link StereoDeviceRenderer#getDistortionBits()}. */
78 public static String distortionBitsToString(final int distortionBits) {
79 boolean appendComma = false;
80 final StringBuilder sb = new StringBuilder();
81 if( usesBarrelDistortion(distortionBits) ) {
82 if( appendComma ) { sb.append(", "); };
83 sb.append("barrel"); appendComma=true;
84 }
85 if( usesVignetteDistortion(distortionBits) ) {
86 if( appendComma ) { sb.append(", "); };
87 sb.append("vignette"); appendComma=true;
88 }
89 if( usesChromaticDistortion(distortionBits) ) {
90 if( appendComma ) { sb.append(", "); };
91 sb.append("chroma"); appendComma=true;
92 }
93 if( usesTimewarpDistortion(distortionBits) ) {
94 if( appendComma ) { sb.append(", "); };
95 sb.append("timewarp"); appendComma=true;
96 }
97 return sb.toString();
98 }
99
100 /** See {@link StereoDevice#getSupportedSensorBits()} and {@link StereoDevice#getEnabledSensorBits()}. */
101 public static boolean usesOrientationSensor(final int sensorBits) { return 0 != ( sensorBits & StereoDevice.SENSOR_ORIENTATION ) ; }
102 /** See {@link StereoDevice#getSupportedSensorBits()} and {@link StereoDevice#getEnabledSensorBits()}. */
103 public static boolean usesYawCorrectionSensor(final int sensorBits) { return 0 != ( sensorBits & StereoDevice.SENSOR_YAW_CORRECTION ) ; }
104 /** See {@link StereoDevice#getSupportedSensorBits()} and {@link StereoDevice#getEnabledSensorBits()}. */
105 public static boolean usesPositionSensor(final int sensorBits) { return 0 != ( sensorBits & StereoDevice.SENSOR_POSITION ) ; }
106
107 /** See {@link StereoDevice#getSupportedSensorBits()} and {@link StereoDevice#getEnabledSensorBits()}. */
108 public static String sensorBitsToString(final int sensorBits) {
109 boolean appendComma = false;
110 final StringBuilder sb = new StringBuilder();
111 if( usesOrientationSensor(sensorBits) ) {
112 if( appendComma ) { sb.append(", "); };
113 sb.append("orientation"); appendComma=true;
114 }
115 if( usesYawCorrectionSensor(sensorBits) ) {
116 if( appendComma ) { sb.append(", "); };
117 sb.append("yaw-corr"); appendComma=true;
118 }
119 if( usesPositionSensor(sensorBits) ) {
120 if( appendComma ) { sb.append(", "); };
121 sb.append("position"); appendComma=true;
122 }
123 return sb.toString();
124 }
125
126 /**
127 * Calculates the <i>Side By Side</i>, SBS, projection- and modelview matrix for one eye.
128 * <p>
129 * {@link #updateViewerPose(int)} must be called upfront.
130 * </p>
131 * <p>
132 * This method merely exist as an example implementation to compute the matrices,
133 * which shall be adopted by the
134 * {@link CustomGLEventListener#reshape(com.jogamp.opengl.GLAutoDrawable, int, int, int, int, EyeParameter, ViewerPose) upstream client code}.
135 * </p>
136 * @param viewerPose
137 * @param eye
138 * @param zNear frustum near value
139 * @param zFar frustum far value
140 * @param mat4Projection projection matrix result
141 * @param mat4Modelview modelview matrix result
142 */
143 public static void getSBSUpstreamPMV(final ViewerPose viewerPose, final Eye eye,
144 final float zNear, final float zFar,
145 final Matrix4f mat4Projection, final Matrix4f mat4Modelview) {
146 final Matrix4f mat4Tmp1 = new Matrix4f();
147 final Matrix4f mat4Tmp2 = new Matrix4f();
148 final Vec3f vec3Tmp1 = new Vec3f();
149 final Vec3f vec3Tmp2 = new Vec3f();
150 final Vec3f vec3Tmp3 = new Vec3f();
151
152 final EyeParameter eyeParam = eye.getEyeParameter();
153
154 //
155 // Projection
156 //
157 mat4Projection.setToPerspective(eyeParam.fovhv, zNear, zFar);
158
159 //
160 // Modelview
161 //
162 final Quaternion rollPitchYaw = new Quaternion();
163 // private final float eyeYaw = FloatUtil.PI; // 180 degrees in radians
164 // rollPitchYaw.rotateByAngleY(eyeYaw);
165 final Vec3f shiftedEyePos = rollPitchYaw.rotateVector(viewerPose.position, vec3Tmp1).add(eyeParam.positionOffset);
166
167 rollPitchYaw.mult(viewerPose.orientation);
168 final Vec3f up = rollPitchYaw.rotateVector(Vec3f.UNIT_Y, vec3Tmp2);
169 final Vec3f forward = rollPitchYaw.rotateVector(Vec3f.UNIT_Z_NEG, vec3Tmp3); // -> center
170 final Vec3f center = forward.add(shiftedEyePos);
171
172 final Matrix4f mLookAt = mat4Tmp2.setToLookAt(shiftedEyePos, center, up, mat4Tmp1);
173 mat4Modelview.mul( mat4Tmp1.setToTranslation( eyeParam.distNoseToPupilX,
174 eyeParam.distMiddleToPupilY,
175 eyeParam.eyeReliefZ ), mLookAt);
176 }
177
178}
Basic 4x4 float matrix implementation using fields for intensive use-cases (host operations).
Definition: Matrix4f.java:89
final Matrix4f mul(final Matrix4f b)
Multiply matrix: [this] = [this] x [b].
Definition: Matrix4f.java:726
Matrix4f setToPerspective(final float fovy_rad, final float aspect, final float zNear, final float zFar)
Set this matrix to perspective frustum projection.
Definition: Matrix4f.java:1303
Matrix4f setToLookAt(final Vec3f eye, final Vec3f center, final Vec3f up, final Matrix4f tmp)
Set this matrix to the look-at matrix based on given parameters.
Definition: Matrix4f.java:1432
final Matrix4f setToTranslation(final float x, final float y, final float z)
Set this matrix to translation.
Definition: Matrix4f.java:887
Quaternion implementation supporting Gimbal-Lock free rotations.
Definition: Quaternion.java:45
final Vec3f rotateVector(final Vec3f vecIn, final Vec3f vecOut)
final Quaternion mult(final Quaternion q)
Multiply this quaternion by the param quaternion.
3D Vector based upon three float components.
Definition: Vec3f.java:37
static final Vec3f UNIT_Z_NEG
Definition: Vec3f.java:44
static final Vec3f UNIT_Y
Definition: Vec3f.java:41
Vec3f add(final float dx, final float dy, final float dz)
this = this + { dx, dy, dz }, returns this.
Definition: Vec3f.java:239
Constant single eye parameter of the viewer, relative to its ViewerPose.
final float distNoseToPupilX
IPD related horizontal distance from nose to pupil in meter.
final FovHVHalves fovhv
Field of view in both directions, may not be centered, either FovHVHalves#inTangents or radians.
final float distMiddleToPupilY
Vertical distance from middle-line to pupil in meter.
final Vec3f positionOffset
eye position vector used to define eye height in meter relative to actor.
final float eyeReliefZ
Z-axis eye relief in meter.
static float[] getHorizPupilCenterFromLeft(final float screenWidthInMeters, final float interpupillaryDistanceInMeters)
Return the horizontal pupil center from the left side for both eyes in the range [0....
Definition: StereoUtil.java:60
static float getVertPupilCenterFromTop(final float screenHeightInMeters, final float pupilCenterFromScreenTopInMeters)
Return the vertical pupil center from the screen top in the range [0..1].
Definition: StereoUtil.java:42
static String distortionBitsToString(final int distortionBits)
See StereoDeviceRenderer#getDistortionBits().
Definition: StereoUtil.java:78
static boolean usesYawCorrectionSensor(final int sensorBits)
See StereoDevice#getSupportedSensorBits() and StereoDevice#getEnabledSensorBits().
static boolean usesOrientationSensor(final int sensorBits)
See StereoDevice#getSupportedSensorBits() and StereoDevice#getEnabledSensorBits().
static boolean usesTimewarpDistortion(final int distortionBits)
See StereoDeviceRenderer#getDistortionBits().
Definition: StereoUtil.java:71
static boolean usesPositionSensor(final int sensorBits)
See StereoDevice#getSupportedSensorBits() and StereoDevice#getEnabledSensorBits().
static void getSBSUpstreamPMV(final ViewerPose viewerPose, final Eye eye, final float zNear, final float zFar, final Matrix4f mat4Projection, final Matrix4f mat4Modelview)
Calculates the Side By Side, SBS, projection- and modelview matrix for one eye.
static boolean usesBarrelDistortion(final int distortionBits)
See StereoDeviceRenderer#getDistortionBits().
Definition: StereoUtil.java:69
static boolean usesVignetteDistortion(final int distortionBits)
See StereoDeviceRenderer#getDistortionBits().
Definition: StereoUtil.java:75
static boolean usesChromaticDistortion(final int distortionBits)
See StereoDeviceRenderer#getDistortionBits().
Definition: StereoUtil.java:73
static String sensorBitsToString(final int sensorBits)
See StereoDevice#getSupportedSensorBits() and StereoDevice#getEnabledSensorBits().
position and orientation of viewer.
Definition: ViewerPose.java:36
final Quaternion orientation
Orientation of viewer.
Definition: ViewerPose.java:50
final Vec3f position
position of viewer in meter.
Definition: ViewerPose.java:47
Interface describing one eye of the stereoscopic device, see StereoDeviceRenderer#getEye(int).
EyeParameter getEyeParameter()
Returns the EyeParameter of this eye.