Переглянути джерело

OculusVR: Get basic projections working (mostly), however, VR cameras still don't work properly

Campbell Suter 8 роки тому
батько
коміт
da52de7f7f

+ 29 - 6
jme3-vr/src/main/java/com/jme3/input/vr/OculusVR.java

@@ -26,6 +26,13 @@ import static org.lwjgl.system.MemoryUtil.*;
 
 /**
  * Oculus VR (LibOVR 1.3.0) Native support.
+ * <p>
+ * A few notes about the Oculus coordinate system:
+ * <ul>
+ * <li>Matrices should be transposed</li>
+ * <li>Quaternions should be inverted<li/>
+ * <li>Vectors should have their X and Z axes flipped, but apparently not Y.</li>
+ * </ul>
  *
  * @author Campbell Suter <[email protected]>
  */
@@ -219,7 +226,6 @@ public class OculusVR implements VRAPI {
         System.out.println("step 5 - projections");
         for (int eye = 0; eye < 2; eye++) {
             projections[eye] = OVRMatrix4f.malloc();
-            OVRUtil.ovrMatrix4f_Projection(fovPorts[eye], 0.5f, 500f, OVRUtil.ovrProjection_None, projections[eye]);
             //1.3 was right handed, now none flag
         }
 
@@ -332,7 +338,7 @@ public class OculusVR implements VRAPI {
 
     @Override
     public Quaternion getOrientation() {
-        return quatO2J(headPose.Orientation(), new Quaternion());
+        return quatO2J(headPose.Orientation(), new Quaternion()).inverseLocal();
     }
 
     @Override
@@ -342,18 +348,31 @@ public class OculusVR implements VRAPI {
 
     @Override
     public void getPositionAndOrientation(Vector3f storePos, Quaternion storeRot) {
-        vecO2J(headPose.Position(), storePos);
-        quatO2J(headPose.Orientation(), storeRot);
+        storePos.set(getPosition());
+        storeRot.set(getOrientation());
+    }
+
+    private Matrix4f calculateProjection(int eye, Camera cam) {
+        Matrix4f mat = new Matrix4f();
+
+        // Get LibOVR to find the correct projection
+        OVRUtil.ovrMatrix4f_Projection(fovPorts[eye], cam.getFrustumNear(), cam.getFrustumFar(), OVRUtil.ovrProjection_None, projections[eye]);
+
+        matrixO2J(projections[eye], mat);
+
+        mat.transposeLocal(); // Apparently LibOVR has a different coordinate set - yay for us.
+
+        return mat;
     }
 
     @Override
     public Matrix4f getHMDMatrixProjectionLeftEye(Camera cam) {
-        return matrixO2J(projections[ovrEye_Left], new Matrix4f());
+        return calculateProjection(ovrEye_Left, cam);
     }
 
     @Override
     public Matrix4f getHMDMatrixProjectionRightEye(Camera cam) {
-        return matrixO2J(projections[ovrEye_Right], new Matrix4f());
+        return calculateProjection(ovrEye_Right, cam);
     }
 
     @Override
@@ -612,6 +631,10 @@ public class OculusVR implements VRAPI {
         return layer0;
     }
 
+    public OVRFovPort getFovPort() {
+        return fovPorts[ovrEye_Left]; // TODO checking the left and right eyes match
+    }
+
     public OVRPosef[] getEyePosesPtr() {
         return eyePosesPtr;
     }

+ 6 - 31
jme3-vr/src/main/java/com/jme3/util/VRViewManagerOculus.java

@@ -34,10 +34,7 @@ package com.jme3.util;
 import com.jme3.app.VREnvironment;
 import com.jme3.input.vr.OculusVR;
 import com.jme3.input.vr.VRAPI;
-import com.jme3.math.ColorRGBA;
-import com.jme3.math.Quaternion;
-import com.jme3.math.Vector2f;
-import com.jme3.math.Vector3f;
+import com.jme3.math.*;
 import com.jme3.renderer.Camera;
 import com.jme3.renderer.ViewPort;
 import com.jme3.scene.Spatial;
@@ -213,16 +210,14 @@ public class VRViewManagerOculus extends AbstractVRViewManager {
             // restore frustrum on distortion scene cam, if needed
             if (environment.isInstanceRendering()) {
                 leftCamera = origCam;
-            } else if (environment.compositorAllowed() == false) {
-                origCam.setFrustumFar(100f);
-                origCam.setFrustumNear(1f);
-                leftCamera = origCam.clone();
-                prepareCameraSize(origCam, 2f);
             } else {
                 leftCamera = origCam.clone();
             }
 
-            getLeftCamera().setFrustumPerspective(environment.getDefaultFOV(), environment.getDefaultAspect(), fNear, fFar);
+            OVRFovPort fp = hardware.getFovPort();
+            float hFov = fp.LeftTan() + fp.RightTan();
+            float vFov = fp.UpTan() + fp.DownTan();
+            getLeftCamera().setFrustumPerspective(hFov / FastMath.TWO_PI * 360, vFov / hFov, fNear, fFar);
 
             prepareCameraSize(getLeftCamera(), 1f);
             if (environment.getVRHardware() != null) {
@@ -238,33 +233,13 @@ public class VRViewManagerOculus extends AbstractVRViewManager {
                 }
                 rightViewPort = setupViewBuffers(getRightCamera(), RIGHT_VIEW_NAME);
             } else if (environment.getApplication() != null) {
-
-                LOG.severe("THIS CODE NEED CHANGES !!!");
-                leftViewPort = environment.getApplication().getViewPort();
-                //leftViewport.attachScene(app.getRootNode());
-                rightCamera = getLeftCamera().clone();
-                if (environment.getVRHardware() != null) {
-                    getRightCamera().setProjectionMatrix(environment.getVRHardware().getHMDMatrixProjectionRightEye(getRightCamera()));
-                }
-
-                org.lwjgl.opengl.GL11.glEnable(org.lwjgl.opengl.GL30.GL_CLIP_DISTANCE0);
-
-                //FIXME: [jme-vr] Fix with JMonkey next release
-                //RenderManager._VRInstancing_RightCamProjection = camRight.getViewProjectionMatrix();
-                // TODO: Add LibOVR support
-                // setupFinalFullTexture(environment.getApplication().getViewPort().getCamera());
+                throw new UnsupportedOperationException("Not yet implemented!");
             } else {
                 throw new IllegalStateException("This VR environment is not attached to any application.");
             }
 
             // setup gui
             environment.getVRGUIManager().setupGui(getLeftCamera(), getRightCamera(), getLeftViewPort(), getRightViewPort());
-
-            if (environment.getVRHardware() != null) {
-                // call these to cache the results internally
-                environment.getVRHardware().getHMDMatrixPoseLeftEye();
-                environment.getVRHardware().getHMDMatrixPoseRightEye();
-            }
         } else {
             throw new IllegalStateException("This VR view manager is not attached to any VR environment.");
         }