Merge pull request #756 from neph1/osvr_viewmanager
making VRViewManagerOSVR more similar to VRViewManagerOpenVR
This commit is contained in:
commit
e4ce70d0ba
@ -1,461 +1,461 @@
|
||||
/*
|
||||
|
||||
https://github.com/sensics/OSVR-RenderManager/blob/master/examples/RenderManagerOpenGLCAPIExample.cpp
|
||||
|
||||
- JVM crashes often.. placing breakpoints during initialization clears it up most of the time (WHY!?)
|
||||
- OSVR is just unstable.. any way to improve things?
|
||||
- render manager looks good, but left eye seems stretched
|
||||
|
||||
*/
|
||||
package com.jme3.input.vr;
|
||||
|
||||
import com.jme3.app.VREnvironment;
|
||||
import com.jme3.math.Matrix4f;
|
||||
import com.jme3.math.Quaternion;
|
||||
import com.jme3.math.Vector2f;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.system.osvr.osvrclientkit.OsvrClientKitLibrary;
|
||||
import com.jme3.system.osvr.osvrdisplay.OsvrDisplayLibrary;
|
||||
import com.jme3.system.osvr.osvrdisplay.OsvrDisplayLibrary.OSVR_DisplayConfig;
|
||||
import com.jme3.system.osvr.osvrmatrixconventions.OSVR_Pose3;
|
||||
import com.jme3.system.osvr.osvrrendermanageropengl.OSVR_OpenResultsOpenGL;
|
||||
import com.jme3.system.osvr.osvrrendermanageropengl.OSVR_RenderBufferOpenGL;
|
||||
import com.jme3.system.osvr.osvrrendermanageropengl.OSVR_RenderInfoOpenGL;
|
||||
import com.jme3.system.osvr.osvrrendermanageropengl.OSVR_RenderParams;
|
||||
import com.jme3.system.osvr.osvrrendermanageropengl.OSVR_ViewportDescription;
|
||||
import com.jme3.system.osvr.osvrrendermanageropengl.OsvrRenderManagerOpenGLLibrary;
|
||||
import com.ochafik.lang.jnaerator.runtime.NativeSize;
|
||||
import com.ochafik.lang.jnaerator.runtime.NativeSizeByReference;
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.ptr.PointerByReference;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* A class that wraps an <a href="http://www.osvr.org/">OSVR</a> system.
|
||||
* @author reden - phr00t - https://github.com/phr00t
|
||||
* @author Julien Seinturier - (c) 2016 - JOrigin project - <a href="http://www.jorigin.org">http:/www.jorigin.org</a>
|
||||
*/
|
||||
public class OSVR implements VRAPI {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(OSVR.class.getName());
|
||||
|
||||
/**
|
||||
* The first viewer index.
|
||||
*/
|
||||
public static final int FIRST_VIEWER = 0;
|
||||
|
||||
/**
|
||||
* The left eye index.
|
||||
*/
|
||||
public static final int EYE_LEFT = 0;
|
||||
|
||||
/**
|
||||
* The right eye index.
|
||||
*/
|
||||
public static final int EYE_RIGHT = 1;
|
||||
|
||||
/**
|
||||
* The size of the left eye.
|
||||
*/
|
||||
public static final NativeSize EYE_LEFT_SIZE = new NativeSize(EYE_LEFT);
|
||||
|
||||
/**
|
||||
* The size of the right eye.
|
||||
*/
|
||||
public static final NativeSize EYE_RIGHT_SIZE = new NativeSize(EYE_RIGHT);
|
||||
|
||||
/**
|
||||
* The default J String.
|
||||
*/
|
||||
public static byte[] defaultJString = { 'j', (byte)0 };
|
||||
|
||||
/**
|
||||
* The default OpenGL String.
|
||||
*/
|
||||
public static byte[] OpenGLString = { 'O', 'p', 'e', 'n', 'G', 'L', (byte)0 };
|
||||
|
||||
private final Matrix4f[] eyeMatrix = new Matrix4f[2];
|
||||
|
||||
private PointerByReference grabRM;
|
||||
private PointerByReference grabRMOGL;
|
||||
private PointerByReference grabRIC;
|
||||
|
||||
OSVR_RenderParams.ByValue renderParams;
|
||||
OsvrClientKitLibrary.OSVR_ClientContext context;
|
||||
com.jme3.system.osvr.osvrrendermanageropengl.OSVR_GraphicsLibraryOpenGL.ByValue graphicsLibrary;
|
||||
Pointer renderManager, renderManagerOpenGL, renderInfoCollection, registerBufferState;
|
||||
OSVRInput VRinput;
|
||||
NativeSize numRenderInfo;
|
||||
NativeSizeByReference grabNumInfo = new NativeSizeByReference();
|
||||
OSVR_RenderInfoOpenGL.ByValue eyeLeftInfo, eyeRightInfo;
|
||||
Matrix4f hmdPoseLeftEye;
|
||||
Matrix4f hmdPoseRightEye;
|
||||
Vector3f hmdPoseLeftEyeVec, hmdPoseRightEyeVec, hmdSeatToStand;
|
||||
OSVR_DisplayConfig displayConfig;
|
||||
OSVR_Pose3 hmdPose = new OSVR_Pose3();
|
||||
Vector3f storePos = new Vector3f();
|
||||
Quaternion storeRot = new Quaternion();
|
||||
PointerByReference presentState = new PointerByReference();
|
||||
OSVR_OpenResultsOpenGL openResults = new OSVR_OpenResultsOpenGL();
|
||||
|
||||
long glfwContext;
|
||||
long renderManagerContext;
|
||||
long wglGLFW;
|
||||
long wglRM;
|
||||
|
||||
boolean initSuccess = false;
|
||||
boolean flipEyes = false;
|
||||
|
||||
private VREnvironment environment = null;
|
||||
|
||||
/**
|
||||
* Create a new <a href="http://www.osvr.org/">OSVR</a> system attached to the given {@link VREnvironment VR environment}.
|
||||
* @param environment the {@link VREnvironment VR environment} to which the input is attached.
|
||||
*/
|
||||
public OSVR(VREnvironment environment){
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access to the underlying OSVR structures.
|
||||
* @param leftView the left viewport.
|
||||
* @param rightView the right viewport.
|
||||
* @param leftBuffer the left buffer.
|
||||
* @param rightBuffer the right buffer.
|
||||
* @return <code>true</code> if the structure are accessible and <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean handleRenderBufferPresent(OSVR_ViewportDescription.ByValue leftView, OSVR_ViewportDescription.ByValue rightView,
|
||||
OSVR_RenderBufferOpenGL.ByValue leftBuffer, OSVR_RenderBufferOpenGL.ByValue rightBuffer) {
|
||||
if( eyeLeftInfo == null || eyeRightInfo == null ) return false;
|
||||
byte retval;
|
||||
OsvrRenderManagerOpenGLLibrary.osvrRenderManagerStartPresentRenderBuffers(presentState);
|
||||
getEyeInfo();
|
||||
OsvrRenderManagerOpenGLLibrary.osvrRenderManagerPresentRenderBufferOpenGL(presentState.getValue(), leftBuffer, eyeLeftInfo, leftView);
|
||||
OsvrRenderManagerOpenGLLibrary.osvrRenderManagerPresentRenderBufferOpenGL(presentState.getValue(), rightBuffer, eyeRightInfo, rightView);
|
||||
retval = OsvrRenderManagerOpenGLLibrary.osvrRenderManagerFinishPresentRenderBuffers(renderManager, presentState.getValue(), renderParams, (byte)0);
|
||||
return retval == 0; // only check the last error, since if something errored above, the last call won't work & all calls will log to syserr
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean initialize() {
|
||||
|
||||
logger.config("Initialize OSVR system.");
|
||||
|
||||
hmdPose.setAutoSynch(false);
|
||||
context = OsvrClientKitLibrary.osvrClientInit(defaultJString, 0);
|
||||
VRinput = new OSVRInput(environment);
|
||||
initSuccess = context != null && VRinput.init();
|
||||
if( initSuccess ) {
|
||||
PointerByReference grabDisplay = new PointerByReference();
|
||||
byte retval = OsvrDisplayLibrary.osvrClientGetDisplay(context, grabDisplay);
|
||||
if( retval != 0 ) {
|
||||
System.out.println("OSVR Get Display Error: " + retval);
|
||||
initSuccess = false;
|
||||
return false;
|
||||
}
|
||||
displayConfig = new OSVR_DisplayConfig(grabDisplay.getValue());
|
||||
System.out.println("Waiting for the display to fully start up, including receiving initial pose update...");
|
||||
int i = 400;
|
||||
while (OsvrDisplayLibrary.osvrClientCheckDisplayStartup(displayConfig) != 0) {
|
||||
if( i-- < 0 ) {
|
||||
System.out.println("Couldn't get display startup update in time, continuing anyway...");
|
||||
break;
|
||||
}
|
||||
OsvrClientKitLibrary.osvrClientUpdate(context);
|
||||
try {
|
||||
Thread.sleep(5);
|
||||
} catch(Exception e) { }
|
||||
}
|
||||
System.out.println("OK, display startup status is good!");
|
||||
}
|
||||
return initSuccess;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Grab the current GLFW context.
|
||||
*/
|
||||
public void grabGLFWContext() {
|
||||
// get current conext
|
||||
wglGLFW = org.lwjgl.opengl.WGL.wglGetCurrentContext();
|
||||
glfwContext = org.lwjgl.glfw.GLFW.glfwGetCurrentContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable context sharing.
|
||||
* @return <code>true</code> if the context is successfully shared and <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean shareContext() {
|
||||
if( org.lwjgl.opengl.WGL.wglShareLists(wglRM, wglGLFW)) {
|
||||
System.out.println("Context sharing success!");
|
||||
return true;
|
||||
} else {
|
||||
System.out.println("Context sharing problem...");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean initVRCompositor(boolean allowed) {
|
||||
if( !allowed || renderManager != null ) return false;
|
||||
grabGLFWContext();
|
||||
graphicsLibrary = new com.jme3.system.osvr.osvrrendermanageropengl.OSVR_GraphicsLibraryOpenGL.ByValue();
|
||||
graphicsLibrary.toolkit = null;
|
||||
graphicsLibrary.setAutoSynch(false);
|
||||
grabRM = new PointerByReference(); grabRMOGL = new PointerByReference();
|
||||
byte retval = OsvrRenderManagerOpenGLLibrary.osvrCreateRenderManagerOpenGL(context, OpenGLString, graphicsLibrary, grabRM, grabRMOGL);
|
||||
if( retval == 0 ) {
|
||||
renderManager = grabRM.getValue(); renderManagerOpenGL = grabRMOGL.getValue();
|
||||
if( renderManager == null || renderManagerOpenGL == null ) {
|
||||
System.out.println("Render Manager Created NULL, error!");
|
||||
return false;
|
||||
}
|
||||
openResults.setAutoSynch(false);
|
||||
retval = OsvrRenderManagerOpenGLLibrary.osvrRenderManagerOpenDisplayOpenGL(renderManager, openResults);
|
||||
if( retval == 0 ) {
|
||||
wglRM = org.lwjgl.opengl.WGL.wglGetCurrentContext();
|
||||
renderManagerContext = org.lwjgl.glfw.GLFW.glfwGetCurrentContext();
|
||||
shareContext();
|
||||
OsvrClientKitLibrary.osvrClientUpdate(context);
|
||||
renderParams = new OSVR_RenderParams.ByValue();
|
||||
renderParams.setAutoSynch(false);
|
||||
OsvrRenderManagerOpenGLLibrary.osvrRenderManagerGetDefaultRenderParams(renderParams);
|
||||
grabRIC = new PointerByReference();
|
||||
retval = OsvrRenderManagerOpenGLLibrary.osvrRenderManagerGetRenderInfoCollection(renderManager, renderParams, grabRIC);
|
||||
if( retval == 0 ) {
|
||||
renderInfoCollection = grabRIC.getValue();
|
||||
OsvrRenderManagerOpenGLLibrary.osvrRenderManagerGetNumRenderInfoInCollection(renderInfoCollection, grabNumInfo);
|
||||
numRenderInfo = grabNumInfo.getValue();
|
||||
eyeLeftInfo = new OSVR_RenderInfoOpenGL.ByValue();
|
||||
eyeRightInfo = new OSVR_RenderInfoOpenGL.ByValue();
|
||||
eyeLeftInfo.setAutoSynch(false);
|
||||
eyeRightInfo.setAutoSynch(false);
|
||||
return true;
|
||||
}
|
||||
OsvrRenderManagerOpenGLLibrary.osvrDestroyRenderManager(renderManager);
|
||||
System.out.println("OSVR Render Manager Info Collection Error: " + retval);
|
||||
return false;
|
||||
}
|
||||
OsvrRenderManagerOpenGLLibrary.osvrDestroyRenderManager(renderManager);
|
||||
System.out.println("OSVR Open Render Manager Display Error: " + retval);
|
||||
return false;
|
||||
}
|
||||
System.out.println("OSVR Create Render Manager Error: " + retval);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OsvrClientKitLibrary.OSVR_ClientContext getVRSystem() {
|
||||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pointer getCompositor() {
|
||||
return renderManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "OSVR";
|
||||
}
|
||||
|
||||
@Override
|
||||
public VRInputAPI getVRinput() {
|
||||
return VRinput;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFlipEyes(boolean set) {
|
||||
flipEyes = set;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printLatencyInfoToConsole(boolean set) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDisplayFrequency() {
|
||||
return 60; //debug display frequency
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
if( renderManager != null ) OsvrRenderManagerOpenGLLibrary.osvrDestroyRenderManager(renderManager);
|
||||
if( displayConfig != null ) OsvrDisplayLibrary.osvrClientFreeDisplay(displayConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInitialized() {
|
||||
return initSuccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
// TODO: no native OSVR reset function
|
||||
// may need to take current position and negate it from future values
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getRenderSize(Vector2f store) {
|
||||
if( eyeLeftInfo == null || eyeLeftInfo.viewport.width == 0.0 ) {
|
||||
store.x = 1280f; store.y = 720f;
|
||||
} else {
|
||||
store.x = (float)eyeLeftInfo.viewport.width;
|
||||
store.y = (float)eyeLeftInfo.viewport.height;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read and update the eye info from the underlying OSVR system.
|
||||
*/
|
||||
public void getEyeInfo() {
|
||||
OsvrRenderManagerOpenGLLibrary.osvrRenderManagerGetRenderInfoFromCollectionOpenGL(renderInfoCollection, EYE_LEFT_SIZE, eyeLeftInfo);
|
||||
OsvrRenderManagerOpenGLLibrary.osvrRenderManagerGetRenderInfoFromCollectionOpenGL(renderInfoCollection, EYE_RIGHT_SIZE, eyeRightInfo);
|
||||
eyeLeftInfo.read(); eyeRightInfo.read();
|
||||
}
|
||||
/*
|
||||
@Override
|
||||
public float getFOV(int dir) {
|
||||
return 105f; //default FOV
|
||||
}
|
||||
*/
|
||||
@Override
|
||||
public float getInterpupillaryDistance() {
|
||||
return 0.065f; //default IPD
|
||||
}
|
||||
|
||||
@Override
|
||||
public Quaternion getOrientation() {
|
||||
storeRot.set((float)-hmdPose.rotation.data[1],
|
||||
(float)hmdPose.rotation.data[2],
|
||||
(float)-hmdPose.rotation.data[3],
|
||||
(float)hmdPose.rotation.data[0]);
|
||||
if( storeRot.equals(Quaternion.ZERO) ) storeRot.set(Quaternion.DIRECTION_Z);
|
||||
return storeRot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3f getPosition() {
|
||||
storePos.x = (float)-hmdPose.translation.data[0];
|
||||
storePos.y = (float)hmdPose.translation.data[1];
|
||||
storePos.z = (float)-hmdPose.translation.data[2];
|
||||
return storePos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getPositionAndOrientation(Vector3f storePos, Quaternion storeRot) {
|
||||
storePos.x = (float)-hmdPose.translation.data[0];
|
||||
storePos.y = (float)hmdPose.translation.data[1];
|
||||
storePos.z = (float)-hmdPose.translation.data[2];
|
||||
storeRot.set((float)-hmdPose.rotation.data[1],
|
||||
(float)hmdPose.rotation.data[2],
|
||||
(float)-hmdPose.rotation.data[3],
|
||||
(float)hmdPose.rotation.data[0]);
|
||||
if( storeRot.equals(Quaternion.ZERO) ) storeRot.set(Quaternion.DIRECTION_Z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePose() {
|
||||
if( context == null || displayConfig == null ) return;
|
||||
OsvrClientKitLibrary.osvrClientUpdate(context);
|
||||
OsvrDisplayLibrary.osvrClientGetViewerPose(displayConfig, FIRST_VIEWER, hmdPose.getPointer());
|
||||
VRinput.updateControllerStates();
|
||||
hmdPose.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Matrix4f getHMDMatrixProjectionLeftEye(Camera cam) {
|
||||
if( eyeLeftInfo == null ) return cam.getProjectionMatrix();
|
||||
if( eyeMatrix[EYE_LEFT] == null ) {
|
||||
FloatBuffer tfb = FloatBuffer.allocate(16);
|
||||
com.jme3.system.osvr.osvrdisplay.OsvrDisplayLibrary.osvrClientGetViewerEyeSurfaceProjectionMatrixf(displayConfig, 0, (byte)EYE_LEFT, 0, cam.getFrustumNear(), cam.getFrustumFar(), (short)0, tfb);
|
||||
eyeMatrix[EYE_LEFT] = new Matrix4f();
|
||||
eyeMatrix[EYE_LEFT].set(tfb.get(0), tfb.get(4), tfb.get(8), tfb.get(12),
|
||||
tfb.get(1), tfb.get(5), tfb.get(9), tfb.get(13),
|
||||
tfb.get(2), tfb.get(6), tfb.get(10), tfb.get(14),
|
||||
tfb.get(3), tfb.get(7), tfb.get(11), tfb.get(15));
|
||||
}
|
||||
return eyeMatrix[EYE_LEFT];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Matrix4f getHMDMatrixProjectionRightEye(Camera cam) {
|
||||
if( eyeRightInfo == null ) return cam.getProjectionMatrix();
|
||||
if( eyeMatrix[EYE_RIGHT] == null ) {
|
||||
FloatBuffer tfb = FloatBuffer.allocate(16);
|
||||
com.jme3.system.osvr.osvrdisplay.OsvrDisplayLibrary.osvrClientGetViewerEyeSurfaceProjectionMatrixf(displayConfig, 0, (byte)EYE_RIGHT, 0, cam.getFrustumNear(), cam.getFrustumFar(), (short)0, tfb);
|
||||
eyeMatrix[EYE_RIGHT] = new Matrix4f();
|
||||
eyeMatrix[EYE_RIGHT].set(tfb.get(0), tfb.get(4), tfb.get(8), tfb.get(12),
|
||||
tfb.get(1), tfb.get(5), tfb.get(9), tfb.get(13),
|
||||
tfb.get(2), tfb.get(6), tfb.get(10), tfb.get(14),
|
||||
tfb.get(3), tfb.get(7), tfb.get(11), tfb.get(15));
|
||||
}
|
||||
return eyeMatrix[EYE_RIGHT];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3f getHMDVectorPoseLeftEye() {
|
||||
if( hmdPoseLeftEyeVec == null ) {
|
||||
hmdPoseLeftEyeVec = new Vector3f();
|
||||
hmdPoseLeftEyeVec.x = 0.065f * -0.5f;
|
||||
if( flipEyes == false ) hmdPoseLeftEyeVec.x *= -1f; // it seems these need flipping
|
||||
}
|
||||
return hmdPoseLeftEyeVec;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3f getHMDVectorPoseRightEye() {
|
||||
if( hmdPoseRightEyeVec == null ) {
|
||||
hmdPoseRightEyeVec = new Vector3f();
|
||||
hmdPoseRightEyeVec.x = 0.065f * 0.5f;
|
||||
if( flipEyes == false ) hmdPoseRightEyeVec.x *= -1f; // it seems these need flipping
|
||||
}
|
||||
return hmdPoseRightEyeVec;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3f getSeatedToAbsolutePosition() {
|
||||
return Vector3f.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Matrix4f getHMDMatrixPoseLeftEye() {
|
||||
// not actually used internally...
|
||||
/*if( hmdPoseLeftEye != null ) {
|
||||
return hmdPoseLeftEye;
|
||||
} else {
|
||||
FloatBuffer mat = FloatBuffer.allocate(16);
|
||||
OsvrDisplayLibrary.osvrClientGetViewerEyeViewMatrixf(displayConfig, FIRST_VIEWER, (byte)EYE_LEFT,
|
||||
(short)(OsvrMatrixConventionsLibrary.OSVR_MatrixVectorFlags.OSVR_MATRIX_COLVECTORS |
|
||||
OsvrMatrixConventionsLibrary.OSVR_MatrixOrderingFlags.OSVR_MATRIX_COLMAJOR), tempfb);
|
||||
hmdPoseLeftEye = new Matrix4f(tempfb.array());
|
||||
return hmdPoseLeftEye;
|
||||
}*/
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Matrix4f getHMDMatrixPoseRightEye() {
|
||||
// not actually used internally...
|
||||
/*if( hmdPoseRightEye != null ) {
|
||||
return hmdPoseRightEye;
|
||||
} else {
|
||||
OsvrDisplayLibrary.osvrClientGetViewerEyeViewMatrixf(displayConfig, FIRST_VIEWER, (byte)EYE_RIGHT,
|
||||
(short)(OsvrMatrixConventionsLibrary.OSVR_MatrixVectorFlags.OSVR_MATRIX_COLVECTORS |
|
||||
OsvrMatrixConventionsLibrary.OSVR_MatrixOrderingFlags.OSVR_MATRIX_COLMAJOR), tempfb);
|
||||
hmdPoseRightEye = new Matrix4f(tempfb.array());
|
||||
return hmdPoseRightEye;
|
||||
}*/
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HmdType getType() {
|
||||
return HmdType.OSVR;
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
https://github.com/sensics/OSVR-RenderManager/blob/master/examples/RenderManagerOpenGLCAPIExample.cpp
|
||||
|
||||
- JVM crashes often.. placing breakpoints during initialization clears it up most of the time (WHY!?)
|
||||
- OSVR is just unstable.. any way to improve things?
|
||||
- render manager looks good, but left eye seems stretched
|
||||
|
||||
*/
|
||||
package com.jme3.input.vr;
|
||||
|
||||
import com.jme3.app.VREnvironment;
|
||||
import com.jme3.math.Matrix4f;
|
||||
import com.jme3.math.Quaternion;
|
||||
import com.jme3.math.Vector2f;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.system.osvr.osvrclientkit.OsvrClientKitLibrary;
|
||||
import com.jme3.system.osvr.osvrdisplay.OsvrDisplayLibrary;
|
||||
import com.jme3.system.osvr.osvrdisplay.OsvrDisplayLibrary.OSVR_DisplayConfig;
|
||||
import com.jme3.system.osvr.osvrmatrixconventions.OSVR_Pose3;
|
||||
import com.jme3.system.osvr.osvrrendermanageropengl.OSVR_OpenResultsOpenGL;
|
||||
import com.jme3.system.osvr.osvrrendermanageropengl.OSVR_RenderBufferOpenGL;
|
||||
import com.jme3.system.osvr.osvrrendermanageropengl.OSVR_RenderInfoOpenGL;
|
||||
import com.jme3.system.osvr.osvrrendermanageropengl.OSVR_RenderParams;
|
||||
import com.jme3.system.osvr.osvrrendermanageropengl.OSVR_ViewportDescription;
|
||||
import com.jme3.system.osvr.osvrrendermanageropengl.OsvrRenderManagerOpenGLLibrary;
|
||||
import com.ochafik.lang.jnaerator.runtime.NativeSize;
|
||||
import com.ochafik.lang.jnaerator.runtime.NativeSizeByReference;
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.ptr.PointerByReference;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* A class that wraps an <a href="http://www.osvr.org/">OSVR</a> system.
|
||||
* @author reden - phr00t - https://github.com/phr00t
|
||||
* @author Julien Seinturier - (c) 2016 - JOrigin project - <a href="http://www.jorigin.org">http:/www.jorigin.org</a>
|
||||
*/
|
||||
public class OSVR implements VRAPI {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(OSVR.class.getName());
|
||||
|
||||
/**
|
||||
* The first viewer index.
|
||||
*/
|
||||
public static final int FIRST_VIEWER = 0;
|
||||
|
||||
/**
|
||||
* The left eye index.
|
||||
*/
|
||||
public static final int EYE_LEFT = 0;
|
||||
|
||||
/**
|
||||
* The right eye index.
|
||||
*/
|
||||
public static final int EYE_RIGHT = 1;
|
||||
|
||||
/**
|
||||
* The size of the left eye.
|
||||
*/
|
||||
public static final NativeSize EYE_LEFT_SIZE = new NativeSize(EYE_LEFT);
|
||||
|
||||
/**
|
||||
* The size of the right eye.
|
||||
*/
|
||||
public static final NativeSize EYE_RIGHT_SIZE = new NativeSize(EYE_RIGHT);
|
||||
|
||||
/**
|
||||
* The default J String.
|
||||
*/
|
||||
public static byte[] defaultJString = { 'j', (byte)0 };
|
||||
|
||||
/**
|
||||
* The default OpenGL String.
|
||||
*/
|
||||
public static byte[] OpenGLString = { 'O', 'p', 'e', 'n', 'G', 'L', (byte)0 };
|
||||
|
||||
private final Matrix4f[] eyeMatrix = new Matrix4f[2];
|
||||
|
||||
private PointerByReference grabRM;
|
||||
private PointerByReference grabRMOGL;
|
||||
private PointerByReference grabRIC;
|
||||
|
||||
OSVR_RenderParams.ByValue renderParams;
|
||||
OsvrClientKitLibrary.OSVR_ClientContext context;
|
||||
com.jme3.system.osvr.osvrrendermanageropengl.OSVR_GraphicsLibraryOpenGL.ByValue graphicsLibrary;
|
||||
Pointer renderManager, renderManagerOpenGL, renderInfoCollection, registerBufferState;
|
||||
OSVRInput VRinput;
|
||||
NativeSize numRenderInfo;
|
||||
NativeSizeByReference grabNumInfo = new NativeSizeByReference();
|
||||
OSVR_RenderInfoOpenGL.ByValue eyeLeftInfo, eyeRightInfo;
|
||||
Matrix4f hmdPoseLeftEye;
|
||||
Matrix4f hmdPoseRightEye;
|
||||
Vector3f hmdPoseLeftEyeVec, hmdPoseRightEyeVec, hmdSeatToStand;
|
||||
OSVR_DisplayConfig displayConfig;
|
||||
OSVR_Pose3 hmdPose = new OSVR_Pose3();
|
||||
Vector3f storePos = new Vector3f();
|
||||
Quaternion storeRot = new Quaternion();
|
||||
PointerByReference presentState = new PointerByReference();
|
||||
OSVR_OpenResultsOpenGL openResults = new OSVR_OpenResultsOpenGL();
|
||||
|
||||
long glfwContext;
|
||||
long renderManagerContext;
|
||||
long wglGLFW;
|
||||
long wglRM;
|
||||
|
||||
boolean initSuccess = false;
|
||||
boolean flipEyes = false;
|
||||
|
||||
private VREnvironment environment = null;
|
||||
|
||||
/**
|
||||
* Create a new <a href="http://www.osvr.org/">OSVR</a> system attached to the given {@link VREnvironment VR environment}.
|
||||
* @param environment the {@link VREnvironment VR environment} to which the input is attached.
|
||||
*/
|
||||
public OSVR(VREnvironment environment){
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access to the underlying OSVR structures.
|
||||
* @param leftView the left viewport.
|
||||
* @param rightView the right viewport.
|
||||
* @param leftBuffer the left buffer.
|
||||
* @param rightBuffer the right buffer.
|
||||
* @return <code>true</code> if the structure are accessible and <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean handleRenderBufferPresent(OSVR_ViewportDescription.ByValue leftView, OSVR_ViewportDescription.ByValue rightView,
|
||||
OSVR_RenderBufferOpenGL.ByValue leftBuffer, OSVR_RenderBufferOpenGL.ByValue rightBuffer) {
|
||||
if( eyeLeftInfo == null || eyeRightInfo == null ) return false;
|
||||
byte retval;
|
||||
OsvrRenderManagerOpenGLLibrary.osvrRenderManagerStartPresentRenderBuffers(presentState);
|
||||
getEyeInfo();
|
||||
OsvrRenderManagerOpenGLLibrary.osvrRenderManagerPresentRenderBufferOpenGL(presentState.getValue(), leftBuffer, eyeLeftInfo, leftView);
|
||||
OsvrRenderManagerOpenGLLibrary.osvrRenderManagerPresentRenderBufferOpenGL(presentState.getValue(), rightBuffer, eyeRightInfo, rightView);
|
||||
retval = OsvrRenderManagerOpenGLLibrary.osvrRenderManagerFinishPresentRenderBuffers(renderManager, presentState.getValue(), renderParams, (byte)0);
|
||||
return retval == 0; // only check the last error, since if something errored above, the last call won't work & all calls will log to syserr
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean initialize() {
|
||||
|
||||
logger.config("Initialize OSVR system.");
|
||||
|
||||
hmdPose.setAutoSynch(false);
|
||||
context = OsvrClientKitLibrary.osvrClientInit(defaultJString, 0);
|
||||
VRinput = new OSVRInput(environment);
|
||||
initSuccess = context != null && VRinput.init();
|
||||
if( initSuccess ) {
|
||||
PointerByReference grabDisplay = new PointerByReference();
|
||||
byte retval = OsvrDisplayLibrary.osvrClientGetDisplay(context, grabDisplay);
|
||||
if( retval != 0 ) {
|
||||
System.out.println("OSVR Get Display Error: " + retval);
|
||||
initSuccess = false;
|
||||
return false;
|
||||
}
|
||||
displayConfig = new OSVR_DisplayConfig(grabDisplay.getValue());
|
||||
System.out.println("Waiting for the display to fully start up, including receiving initial pose update...");
|
||||
int i = 400;
|
||||
while (OsvrDisplayLibrary.osvrClientCheckDisplayStartup(displayConfig) != 0) {
|
||||
if( i-- < 0 ) {
|
||||
System.out.println("Couldn't get display startup update in time, continuing anyway...");
|
||||
break;
|
||||
}
|
||||
OsvrClientKitLibrary.osvrClientUpdate(context);
|
||||
try {
|
||||
Thread.sleep(5);
|
||||
} catch(Exception e) { }
|
||||
}
|
||||
System.out.println("OK, display startup status is good!");
|
||||
}
|
||||
return initSuccess;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Grab the current GLFW context.
|
||||
*/
|
||||
public void grabGLFWContext() {
|
||||
// get current conext
|
||||
wglGLFW = org.lwjgl.opengl.WGL.wglGetCurrentContext();
|
||||
glfwContext = org.lwjgl.glfw.GLFW.glfwGetCurrentContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable context sharing.
|
||||
* @return <code>true</code> if the context is successfully shared and <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean shareContext() {
|
||||
if( org.lwjgl.opengl.WGL.wglShareLists(wglRM, wglGLFW)) {
|
||||
System.out.println("Context sharing success!");
|
||||
return true;
|
||||
} else {
|
||||
System.out.println("Context sharing problem...");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean initVRCompositor(boolean allowed) {
|
||||
if( !allowed || renderManager != null ) return false;
|
||||
grabGLFWContext();
|
||||
graphicsLibrary = new com.jme3.system.osvr.osvrrendermanageropengl.OSVR_GraphicsLibraryOpenGL.ByValue();
|
||||
graphicsLibrary.toolkit = null;
|
||||
graphicsLibrary.setAutoSynch(false);
|
||||
grabRM = new PointerByReference(); grabRMOGL = new PointerByReference();
|
||||
byte retval = OsvrRenderManagerOpenGLLibrary.osvrCreateRenderManagerOpenGL(context, OpenGLString, graphicsLibrary, grabRM, grabRMOGL);
|
||||
if( retval == 0 ) {
|
||||
renderManager = grabRM.getValue(); renderManagerOpenGL = grabRMOGL.getValue();
|
||||
if( renderManager == null || renderManagerOpenGL == null ) {
|
||||
System.out.println("Render Manager Created NULL, error!");
|
||||
return false;
|
||||
}
|
||||
openResults.setAutoSynch(false);
|
||||
retval = OsvrRenderManagerOpenGLLibrary.osvrRenderManagerOpenDisplayOpenGL(renderManager, openResults);
|
||||
if( retval == 0 ) {
|
||||
wglRM = org.lwjgl.opengl.WGL.wglGetCurrentContext();
|
||||
renderManagerContext = org.lwjgl.glfw.GLFW.glfwGetCurrentContext();
|
||||
shareContext();
|
||||
OsvrClientKitLibrary.osvrClientUpdate(context);
|
||||
renderParams = new OSVR_RenderParams.ByValue();
|
||||
renderParams.setAutoSynch(false);
|
||||
OsvrRenderManagerOpenGLLibrary.osvrRenderManagerGetDefaultRenderParams(renderParams);
|
||||
grabRIC = new PointerByReference();
|
||||
retval = OsvrRenderManagerOpenGLLibrary.osvrRenderManagerGetRenderInfoCollection(renderManager, renderParams, grabRIC);
|
||||
if( retval == 0 ) {
|
||||
renderInfoCollection = grabRIC.getValue();
|
||||
OsvrRenderManagerOpenGLLibrary.osvrRenderManagerGetNumRenderInfoInCollection(renderInfoCollection, grabNumInfo);
|
||||
numRenderInfo = grabNumInfo.getValue();
|
||||
eyeLeftInfo = new OSVR_RenderInfoOpenGL.ByValue();
|
||||
eyeRightInfo = new OSVR_RenderInfoOpenGL.ByValue();
|
||||
eyeLeftInfo.setAutoSynch(false);
|
||||
eyeRightInfo.setAutoSynch(false);
|
||||
return true;
|
||||
}
|
||||
OsvrRenderManagerOpenGLLibrary.osvrDestroyRenderManager(renderManager);
|
||||
System.out.println("OSVR Render Manager Info Collection Error: " + retval);
|
||||
return false;
|
||||
}
|
||||
OsvrRenderManagerOpenGLLibrary.osvrDestroyRenderManager(renderManager);
|
||||
System.out.println("OSVR Open Render Manager Display Error: " + retval);
|
||||
return false;
|
||||
}
|
||||
System.out.println("OSVR Create Render Manager Error: " + retval);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OsvrClientKitLibrary.OSVR_ClientContext getVRSystem() {
|
||||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pointer getCompositor() {
|
||||
return renderManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "OSVR";
|
||||
}
|
||||
|
||||
@Override
|
||||
public VRInputAPI getVRinput() {
|
||||
return VRinput;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFlipEyes(boolean set) {
|
||||
flipEyes = set;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printLatencyInfoToConsole(boolean set) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDisplayFrequency() {
|
||||
return 60; //debug display frequency
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
if( renderManager != null ) OsvrRenderManagerOpenGLLibrary.osvrDestroyRenderManager(renderManager);
|
||||
if( displayConfig != null ) OsvrDisplayLibrary.osvrClientFreeDisplay(displayConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInitialized() {
|
||||
return initSuccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
// TODO: no native OSVR reset function
|
||||
// may need to take current position and negate it from future values
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getRenderSize(Vector2f store) {
|
||||
if( eyeLeftInfo == null || eyeLeftInfo.viewport.width == 0.0 ) {
|
||||
store.x = 1280f; store.y = 720f;
|
||||
} else {
|
||||
store.x = (float)eyeLeftInfo.viewport.width;
|
||||
store.y = (float)eyeLeftInfo.viewport.height;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read and update the eye info from the underlying OSVR system.
|
||||
*/
|
||||
public void getEyeInfo() {
|
||||
OsvrRenderManagerOpenGLLibrary.osvrRenderManagerGetRenderInfoFromCollectionOpenGL(renderInfoCollection, EYE_LEFT_SIZE, eyeLeftInfo);
|
||||
OsvrRenderManagerOpenGLLibrary.osvrRenderManagerGetRenderInfoFromCollectionOpenGL(renderInfoCollection, EYE_RIGHT_SIZE, eyeRightInfo);
|
||||
eyeLeftInfo.read(); eyeRightInfo.read();
|
||||
}
|
||||
/*
|
||||
@Override
|
||||
public float getFOV(int dir) {
|
||||
return 105f; //default FOV
|
||||
}
|
||||
*/
|
||||
@Override
|
||||
public float getInterpupillaryDistance() {
|
||||
return 0.065f; //default IPD
|
||||
}
|
||||
|
||||
@Override
|
||||
public Quaternion getOrientation() {
|
||||
storeRot.set((float)hmdPose.rotation.data[1],
|
||||
(float)hmdPose.rotation.data[2],
|
||||
(float)hmdPose.rotation.data[3],
|
||||
(float)hmdPose.rotation.data[0]);
|
||||
if( storeRot.equals(Quaternion.ZERO) ) storeRot.set(Quaternion.DIRECTION_Z);
|
||||
return storeRot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3f getPosition() {
|
||||
storePos.x = (float)-hmdPose.translation.data[0];
|
||||
storePos.y = (float)hmdPose.translation.data[1];
|
||||
storePos.z = (float)-hmdPose.translation.data[2];
|
||||
return storePos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getPositionAndOrientation(Vector3f storePos, Quaternion storeRot) {
|
||||
storePos.x = (float)-hmdPose.translation.data[0];
|
||||
storePos.y = (float)hmdPose.translation.data[1];
|
||||
storePos.z = (float)-hmdPose.translation.data[2];
|
||||
storeRot.set((float)hmdPose.rotation.data[1],
|
||||
(float)hmdPose.rotation.data[2],
|
||||
(float)hmdPose.rotation.data[3],
|
||||
(float)hmdPose.rotation.data[0]);
|
||||
if( storeRot.equals(Quaternion.ZERO) ) storeRot.set(Quaternion.DIRECTION_Z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePose() {
|
||||
if( context == null || displayConfig == null ) return;
|
||||
OsvrClientKitLibrary.osvrClientUpdate(context);
|
||||
OsvrDisplayLibrary.osvrClientGetViewerPose(displayConfig, FIRST_VIEWER, hmdPose.getPointer());
|
||||
VRinput.updateControllerStates();
|
||||
hmdPose.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Matrix4f getHMDMatrixProjectionLeftEye(Camera cam) {
|
||||
if( eyeLeftInfo == null ) return cam.getProjectionMatrix();
|
||||
if( eyeMatrix[EYE_LEFT] == null ) {
|
||||
FloatBuffer tfb = FloatBuffer.allocate(16);
|
||||
com.jme3.system.osvr.osvrdisplay.OsvrDisplayLibrary.osvrClientGetViewerEyeSurfaceProjectionMatrixf(displayConfig, 0, (byte)EYE_LEFT, 0, cam.getFrustumNear(), cam.getFrustumFar(), (short)0, tfb);
|
||||
eyeMatrix[EYE_LEFT] = new Matrix4f();
|
||||
eyeMatrix[EYE_LEFT].set(tfb.get(0), tfb.get(4), tfb.get(8), tfb.get(12),
|
||||
tfb.get(1), tfb.get(5), tfb.get(9), tfb.get(13),
|
||||
tfb.get(2), tfb.get(6), tfb.get(10), tfb.get(14),
|
||||
tfb.get(3), tfb.get(7), tfb.get(11), tfb.get(15));
|
||||
}
|
||||
return eyeMatrix[EYE_LEFT];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Matrix4f getHMDMatrixProjectionRightEye(Camera cam) {
|
||||
if( eyeRightInfo == null ) return cam.getProjectionMatrix();
|
||||
if( eyeMatrix[EYE_RIGHT] == null ) {
|
||||
FloatBuffer tfb = FloatBuffer.allocate(16);
|
||||
com.jme3.system.osvr.osvrdisplay.OsvrDisplayLibrary.osvrClientGetViewerEyeSurfaceProjectionMatrixf(displayConfig, 0, (byte)EYE_RIGHT, 0, cam.getFrustumNear(), cam.getFrustumFar(), (short)0, tfb);
|
||||
eyeMatrix[EYE_RIGHT] = new Matrix4f();
|
||||
eyeMatrix[EYE_RIGHT].set(tfb.get(0), tfb.get(4), tfb.get(8), tfb.get(12),
|
||||
tfb.get(1), tfb.get(5), tfb.get(9), tfb.get(13),
|
||||
tfb.get(2), tfb.get(6), tfb.get(10), tfb.get(14),
|
||||
tfb.get(3), tfb.get(7), tfb.get(11), tfb.get(15));
|
||||
}
|
||||
return eyeMatrix[EYE_RIGHT];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3f getHMDVectorPoseLeftEye() {
|
||||
if( hmdPoseLeftEyeVec == null ) {
|
||||
hmdPoseLeftEyeVec = new Vector3f();
|
||||
hmdPoseLeftEyeVec.x = 0.065f * -0.5f;
|
||||
if( flipEyes == false ) hmdPoseLeftEyeVec.x *= -1f; // it seems these need flipping
|
||||
}
|
||||
return hmdPoseLeftEyeVec;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3f getHMDVectorPoseRightEye() {
|
||||
if( hmdPoseRightEyeVec == null ) {
|
||||
hmdPoseRightEyeVec = new Vector3f();
|
||||
hmdPoseRightEyeVec.x = 0.065f * 0.5f;
|
||||
if( flipEyes == false ) hmdPoseRightEyeVec.x *= -1f; // it seems these need flipping
|
||||
}
|
||||
return hmdPoseRightEyeVec;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3f getSeatedToAbsolutePosition() {
|
||||
return Vector3f.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Matrix4f getHMDMatrixPoseLeftEye() {
|
||||
// not actually used internally...
|
||||
/*if( hmdPoseLeftEye != null ) {
|
||||
return hmdPoseLeftEye;
|
||||
} else {
|
||||
FloatBuffer mat = FloatBuffer.allocate(16);
|
||||
OsvrDisplayLibrary.osvrClientGetViewerEyeViewMatrixf(displayConfig, FIRST_VIEWER, (byte)EYE_LEFT,
|
||||
(short)(OsvrMatrixConventionsLibrary.OSVR_MatrixVectorFlags.OSVR_MATRIX_COLVECTORS |
|
||||
OsvrMatrixConventionsLibrary.OSVR_MatrixOrderingFlags.OSVR_MATRIX_COLMAJOR), tempfb);
|
||||
hmdPoseLeftEye = new Matrix4f(tempfb.array());
|
||||
return hmdPoseLeftEye;
|
||||
}*/
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Matrix4f getHMDMatrixPoseRightEye() {
|
||||
// not actually used internally...
|
||||
/*if( hmdPoseRightEye != null ) {
|
||||
return hmdPoseRightEye;
|
||||
} else {
|
||||
OsvrDisplayLibrary.osvrClientGetViewerEyeViewMatrixf(displayConfig, FIRST_VIEWER, (byte)EYE_RIGHT,
|
||||
(short)(OsvrMatrixConventionsLibrary.OSVR_MatrixVectorFlags.OSVR_MATRIX_COLVECTORS |
|
||||
OsvrMatrixConventionsLibrary.OSVR_MatrixOrderingFlags.OSVR_MATRIX_COLMAJOR), tempfb);
|
||||
hmdPoseRightEye = new Matrix4f(tempfb.array());
|
||||
return hmdPoseRightEye;
|
||||
}*/
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HmdType getType() {
|
||||
return HmdType.OSVR;
|
||||
}
|
||||
}
|
||||
|
@ -50,18 +50,6 @@ import com.sun.jna.ptr.PointerByReference;
|
||||
public class VRViewManagerOSVR extends AbstractVRViewManager{
|
||||
private static final Logger logger = Logger.getLogger(VRViewManagerOpenVR.class.getName());
|
||||
|
||||
private Camera leftCamera;
|
||||
private ViewPort leftViewport;
|
||||
private FilterPostProcessor leftPostProcessor;
|
||||
private Texture2D leftEyeTexture;
|
||||
private Texture2D leftEyeDepth;
|
||||
|
||||
private Camera rightCamera;
|
||||
private ViewPort rightViewport;
|
||||
private FilterPostProcessor rightPostProcessor;
|
||||
private Texture2D rightEyeTexture;
|
||||
private Texture2D rightEyeDepth;
|
||||
|
||||
// OpenVR values
|
||||
private Texture_t leftTextureType;
|
||||
private Texture_t rightTextureType;
|
||||
@ -73,15 +61,10 @@ public class VRViewManagerOSVR extends AbstractVRViewManager{
|
||||
OSVR_ViewportDescription.ByValue osvr_viewDescRight;
|
||||
Pointer osvr_rmBufferState;
|
||||
|
||||
//private static boolean useCustomDistortion;
|
||||
private float heightAdjustment;
|
||||
|
||||
private Texture2D dualEyeTex;
|
||||
|
||||
private final PointerByReference grabRBS = new PointerByReference();
|
||||
|
||||
private float resMult = 1f;
|
||||
|
||||
//final & temp values for camera calculations
|
||||
private final Vector3f finalPosition = new Vector3f();
|
||||
private final Quaternion finalRotation = new Quaternion();
|
||||
@ -96,42 +79,6 @@ public class VRViewManagerOSVR extends AbstractVRViewManager{
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link Camera camera} attached to the left eye.
|
||||
* @return the {@link Camera camera} attached to the left eye.
|
||||
* @see #getRightCamera()
|
||||
*/
|
||||
public Camera getLeftCamera() {
|
||||
return leftCamera;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link Camera camera} attached to the right eye.
|
||||
* @return the {@link Camera camera} attached to the right eye.
|
||||
* @see #getLeftCamera()
|
||||
*/
|
||||
public Camera getRightCamera() {
|
||||
return rightCamera;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link ViewPort viewport} attached to the left eye.
|
||||
* @return the {@link ViewPort viewport} attached to the left eye.
|
||||
* @see #getRightViewPort()
|
||||
*/
|
||||
public ViewPort getLeftViewPort() {
|
||||
return leftViewport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link ViewPort viewport} attached to the right eye.
|
||||
* @return the {@link ViewPort viewport} attached to the right eye.
|
||||
* @see #getLeftViewPort()
|
||||
*/
|
||||
public ViewPort getRightViewPort() {
|
||||
return rightViewport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the identifier of the left eye texture.
|
||||
* @return the identifier of the left eye texture.
|
||||
@ -162,42 +109,6 @@ public class VRViewManagerOSVR extends AbstractVRViewManager{
|
||||
return (int)dualEyeTex.getImage().getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the height adjustment to apply to the cameras before rendering.
|
||||
* @return the height adjustment to apply to the cameras before rendering.
|
||||
* @see #setHeightAdjustment(float)
|
||||
*/
|
||||
public float getHeightAdjustment() {
|
||||
return heightAdjustment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the height adjustment to apply to the cameras before rendering.
|
||||
* @param amount the height adjustment to apply to the cameras before rendering.
|
||||
* @see #getHeightAdjustment()
|
||||
*/
|
||||
public void setHeightAdjustment(float amount) {
|
||||
heightAdjustment = amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the resolution multiplier.
|
||||
* @return the resolution multiplier.
|
||||
* @see #setResolutionMultiplier(float)
|
||||
*/
|
||||
public float getResolutionMuliplier() {
|
||||
return resMult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the resolution multiplier.
|
||||
* @param resMult the resolution multiplier.
|
||||
* @see #getResolutionMuliplier()
|
||||
*/
|
||||
public void setResolutionMultiplier(float resMult) {
|
||||
this.resMult = resMult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the system binds of the textures.
|
||||
*/
|
||||
@ -442,8 +353,8 @@ public class VRViewManagerOSVR extends AbstractVRViewManager{
|
||||
|
||||
// other adjustments
|
||||
size.x *= xMult;
|
||||
size.x *= resMult;
|
||||
size.y *= resMult;
|
||||
size.x *= getResolutionMuliplier();
|
||||
size.y *= getResolutionMuliplier();
|
||||
|
||||
if( cam.getWidth() != size.x || cam.getHeight() != size.y ){
|
||||
cam.resize((int)size.x, (int)size.y, false);
|
||||
@ -469,10 +380,10 @@ public class VRViewManagerOSVR extends AbstractVRViewManager{
|
||||
return;
|
||||
}
|
||||
|
||||
leftEyeTexture = (Texture2D) leftViewport.getOutputFrameBuffer().getColorBuffer().getTexture();
|
||||
rightEyeTexture = (Texture2D)rightViewport.getOutputFrameBuffer().getColorBuffer().getTexture();
|
||||
leftEyeDepth = (Texture2D) leftViewport.getOutputFrameBuffer().getDepthBuffer().getTexture();
|
||||
rightEyeDepth = (Texture2D)rightViewport.getOutputFrameBuffer().getDepthBuffer().getTexture();
|
||||
leftEyeTexture = (Texture2D) getLeftViewPort().getOutputFrameBuffer().getColorBuffer().getTexture();
|
||||
rightEyeTexture = (Texture2D)getRightViewPort().getOutputFrameBuffer().getColorBuffer().getTexture();
|
||||
leftEyeDepth = (Texture2D) getLeftViewPort().getOutputFrameBuffer().getDepthBuffer().getTexture();
|
||||
rightEyeDepth = (Texture2D)getRightViewPort().getOutputFrameBuffer().getDepthBuffer().getTexture();
|
||||
|
||||
// main viewport is either going to be a distortion scene or nothing
|
||||
// mirroring is handled by copying framebuffers
|
||||
@ -587,7 +498,7 @@ public class VRViewManagerOSVR extends AbstractVRViewManager{
|
||||
if( obsPosition != null ){
|
||||
finalPosition.addLocal(obsPosition);
|
||||
}
|
||||
finalPosition.y += heightAdjustment;
|
||||
finalPosition.y += getHeightAdjustment();
|
||||
cam.setFrame(finalPosition, finalRotation);
|
||||
}
|
||||
|
||||
@ -595,7 +506,7 @@ public class VRViewManagerOSVR extends AbstractVRViewManager{
|
||||
* Handles moving filters from the main view to each eye
|
||||
*/
|
||||
public void moveScreenProcessingToEyes() {
|
||||
if( rightViewport == null ){
|
||||
if( getRightViewPort() == null ){
|
||||
return;
|
||||
}
|
||||
|
||||
@ -617,7 +528,7 @@ public class VRViewManagerOSVR extends AbstractVRViewManager{
|
||||
* @param sourceViewport the {@link ViewPort viewport} that contains the processors to use.
|
||||
*/
|
||||
public void syncScreenProcessing(ViewPort sourceViewport) {
|
||||
if( rightViewport == null ){
|
||||
if( getRightViewPort() == null ){
|
||||
return;
|
||||
}
|
||||
|
||||
@ -631,13 +542,13 @@ public class VRViewManagerOSVR extends AbstractVRViewManager{
|
||||
// clear out all filters & processors, to start from scratch
|
||||
rightPostProcessor.removeAllFilters();
|
||||
leftPostProcessor.removeAllFilters();
|
||||
leftViewport.clearProcessors();
|
||||
rightViewport.clearProcessors();
|
||||
getLeftViewPort().clearProcessors();
|
||||
getRightViewPort().clearProcessors();
|
||||
// if we have no processors to sync, don't add the FilterPostProcessor
|
||||
if( sourceViewport.getProcessors().isEmpty() ) return;
|
||||
// add post processors we just made, which are empty
|
||||
leftViewport.addProcessor(leftPostProcessor);
|
||||
rightViewport.addProcessor(rightPostProcessor);
|
||||
getLeftViewPort().addProcessor(leftPostProcessor);
|
||||
getRightViewPort().addProcessor(rightPostProcessor);
|
||||
// go through all of the filters in the processors list
|
||||
// add them to the left viewport processor & clone them to the right
|
||||
for(SceneProcessor sceneProcessor : sourceViewport.getProcessors()) {
|
||||
@ -670,8 +581,8 @@ public class VRViewManagerOSVR extends AbstractVRViewManager{
|
||||
VRDirectionalLightShadowRenderer dlsr = (VRDirectionalLightShadowRenderer) sceneProcessor;
|
||||
VRDirectionalLightShadowRenderer dlsrRight = dlsr.clone();
|
||||
dlsrRight.setLight(dlsr.getLight());
|
||||
rightViewport.getProcessors().add(0, dlsrRight);
|
||||
leftViewport.getProcessors().add(0, sceneProcessor);
|
||||
getRightViewPort().getProcessors().add(0, dlsrRight);
|
||||
getLeftViewPort().getProcessors().add(0, sceneProcessor);
|
||||
}
|
||||
}
|
||||
// make sure each has a translucent filter renderer
|
||||
@ -718,16 +629,16 @@ public class VRViewManagerOSVR extends AbstractVRViewManager{
|
||||
//org.lwjgl.opengl.GL11.glEnable(org.lwjgl.opengl.GL30.GL_FRAMEBUFFER_SRGB);
|
||||
|
||||
if( !environment.isInstanceRendering()) {
|
||||
leftViewport = setupViewBuffers(leftCamera, LEFT_VIEW_NAME);
|
||||
leftViewPort = setupViewBuffers(leftCamera, LEFT_VIEW_NAME);
|
||||
rightCamera = leftCamera.clone();
|
||||
if( environment.getVRHardware() != null ){
|
||||
rightCamera.setProjectionMatrix(environment.getVRHardware().getHMDMatrixProjectionRightEye(rightCamera));
|
||||
}
|
||||
rightViewport = setupViewBuffers(rightCamera, RIGHT_VIEW_NAME);
|
||||
rightViewPort = setupViewBuffers(rightCamera, RIGHT_VIEW_NAME);
|
||||
} else {
|
||||
|
||||
System.err.println("[VRViewManager] THIS CODE NEED CHANGES !!!");
|
||||
leftViewport = environment.getApplication().getViewPort();
|
||||
leftViewPort = environment.getApplication().getViewPort();
|
||||
//leftViewport.attachScene(app.getRootNode());
|
||||
rightCamera = leftCamera.clone();
|
||||
if( environment.getVRHardware() != null ){
|
||||
@ -742,7 +653,7 @@ public class VRViewManagerOSVR extends AbstractVRViewManager{
|
||||
}
|
||||
|
||||
// setup gui
|
||||
environment.getVRGUIManager().setupGui(leftCamera, rightCamera, leftViewport, rightViewport);
|
||||
environment.getVRGUIManager().setupGui(leftCamera, rightCamera, getLeftViewPort(), getRightViewPort());
|
||||
|
||||
if( environment.getVRHardware() != null ) {
|
||||
// call these to cache the results internally
|
||||
|
Loading…
x
Reference in New Issue
Block a user