Ver código fonte

Changing back orientation quat modification

Rickard Edén 8 anos atrás
pai
commit
30de635cdf
1 arquivos alterados com 461 adições e 461 exclusões
  1. 461 461
      jme3-vr/src/main/java/com/jme3/input/vr/OSVR.java

+ 461 - 461
jme3-vr/src/main/java/com/jme3/input/vr/OSVR.java

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