|
@@ -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;
|
|
|
|
+ }
|
|
|
|
+}
|