diff --git a/.gitignore b/.gitignore
index aa848af79..dc6d9aec8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,3 +43,4 @@
!/jme3-vr/src/main/resources/**/*.so.dbg
!/jme3-vr/src/main/resources/**/*.dll
!/jme3-vr/src/main/resources/**/*.pdb
+/buildMaven.bat
diff --git a/jme3-vr/src/main/java/com/jme3/app/VRAppState.java b/jme3-vr/src/main/java/com/jme3/app/VRAppState.java
index 5b850c931..a468e71b9 100644
--- a/jme3-vr/src/main/java/com/jme3/app/VRAppState.java
+++ b/jme3-vr/src/main/java/com/jme3/app/VRAppState.java
@@ -241,7 +241,7 @@ public class VRAppState extends AbstractAppState {
return application.getViewPort();
}
- return environment.getVRViewManager().getLeftViewport();
+ return environment.getVRViewManager().getLeftViewPort();
}
/**
@@ -253,7 +253,7 @@ public class VRAppState extends AbstractAppState {
if( environment.getVRViewManager() == null ){
return application.getViewPort();
}
- return environment.getVRViewManager().getRightViewport();
+ return environment.getVRViewManager().getRightViewPort();
}
/**
@@ -263,12 +263,12 @@ public class VRAppState extends AbstractAppState {
public void setBackgroundColors(ColorRGBA clr) {
if( environment.getVRViewManager() == null ) {
application.getViewPort().setBackgroundColor(clr);
- } else if( environment.getVRViewManager().getLeftViewport() != null ) {
+ } else if( environment.getVRViewManager().getLeftViewPort() != null ) {
- environment.getVRViewManager().getLeftViewport().setBackgroundColor(clr);
+ environment.getVRViewManager().getLeftViewPort().setBackgroundColor(clr);
- if( environment.getVRViewManager().getRightViewport() != null ){
- environment.getVRViewManager().getRightViewport().setBackgroundColor(clr);
+ if( environment.getVRViewManager().getRightViewPort() != null ){
+ environment.getVRViewManager().getRightViewPort().setBackgroundColor(clr);
}
}
}
diff --git a/jme3-vr/src/main/java/com/jme3/app/VRApplication.java b/jme3-vr/src/main/java/com/jme3/app/VRApplication.java
index 698451248..9d502431d 100644
--- a/jme3-vr/src/main/java/com/jme3/app/VRApplication.java
+++ b/jme3-vr/src/main/java/com/jme3/app/VRApplication.java
@@ -254,7 +254,7 @@ public abstract class VRApplication implements Application, SystemListener {
dummyCam = new Camera();
initStateManager();
-
+
// Create the GUI manager.
guiManager = new VRGuiManager(null);
@@ -1085,7 +1085,7 @@ public abstract class VRApplication implements Application, SystemListener {
*/
public ViewPort getLeftViewPort() {
if( viewmanager == null ) return getViewPort();
- return viewmanager.getLeftViewport();
+ return viewmanager.getLeftViewPort();
}
/**
@@ -1095,7 +1095,7 @@ public abstract class VRApplication implements Application, SystemListener {
*/
public ViewPort getRightViewPort() {
if( viewmanager == null ) return getViewPort();
- return viewmanager.getRightViewport();
+ return viewmanager.getRightViewPort();
}
@@ -1106,9 +1106,9 @@ public abstract class VRApplication implements Application, SystemListener {
public void setBackgroundColors(ColorRGBA clr) {
if( viewmanager == null ) {
getViewPort().setBackgroundColor(clr);
- } else if( viewmanager.getLeftViewport() != null ) {
- viewmanager.getLeftViewport().setBackgroundColor(clr);
- if( viewmanager.getRightViewport() != null ) viewmanager.getRightViewport().setBackgroundColor(clr);
+ } else if( viewmanager.getLeftViewPort() != null ) {
+ viewmanager.getLeftViewPort().setBackgroundColor(clr);
+ if( viewmanager.getRightViewPort() != null ) viewmanager.getRightViewPort().setBackgroundColor(clr);
}
}
diff --git a/jme3-vr/src/main/java/com/jme3/app/VREnvironment.java b/jme3-vr/src/main/java/com/jme3/app/VREnvironment.java
index 5358ff42a..e0e9048dc 100644
--- a/jme3-vr/src/main/java/com/jme3/app/VREnvironment.java
+++ b/jme3-vr/src/main/java/com/jme3/app/VREnvironment.java
@@ -8,6 +8,7 @@ import com.jme3.app.state.AppState;
import com.jme3.input.vr.OSVR;
import com.jme3.input.vr.OpenVR;
import com.jme3.input.vr.VRAPI;
+import com.jme3.input.vr.VRBounds;
import com.jme3.input.vr.VRInputAPI;
import com.jme3.renderer.Camera;
import com.jme3.scene.Spatial;
@@ -28,6 +29,8 @@ public class VREnvironment {
private VRMouseManager mouseManager = null;
private VRViewManager viewmanager = null;
+ private VRBounds bounds = null;
+
/**
* The underlying system VR API. By default set to {@link VRConstants#SETTING_VRAPI_OPENVR_VALUE}.
*/
@@ -65,7 +68,6 @@ public class VREnvironment {
private boolean initialized = false;
- private boolean attached = false;
public VREnvironment(AppSettings settings){
@@ -73,7 +75,8 @@ public class VREnvironment {
guiManager = new VRGuiManager(this);
mouseManager = new VRMouseManager(this);
-// dummyCam = new Camera(settings.getWidth(), settings.getHeight());
+
+ bounds = new VRBounds();
processSettings();
}
@@ -86,6 +89,14 @@ public class VREnvironment {
return hardware;
}
+ /**
+ * Get the VR bounds.
+ * @return the VR bounds.
+ */
+ public VRBounds getVRBounds(){
+ return bounds;
+ }
+
/**
* Get the VR dedicated input.
* @return the VR dedicated input.
@@ -347,7 +358,12 @@ public class VREnvironment {
if (application.getCamera() != null){
dummyCam = application.getCamera().clone();
} else {
- return new Camera(settings.getWidth(), settings.getHeight());
+
+ if ((settings != null) && (settings.getWidth() != 0) && (settings.getHeight() != 0)){
+ dummyCam = new Camera(settings.getWidth(), settings.getHeight());
+ } else {
+ dummyCam = new Camera();
+ }
}
} else {
throw new IllegalStateException("VR environment is not attached to any application.");
diff --git a/jme3-vr/src/main/java/com/jme3/input/vr/OpenVR.java b/jme3-vr/src/main/java/com/jme3/input/vr/OpenVR.java
index 8171bc48a..a9f3fdcfb 100644
--- a/jme3-vr/src/main/java/com/jme3/input/vr/OpenVR.java
+++ b/jme3-vr/src/main/java/com/jme3/input/vr/OpenVR.java
@@ -1,524 +1,525 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-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.jopenvr.HmdMatrix34_t;
-import com.jme3.system.jopenvr.HmdMatrix44_t;
-import com.jme3.system.jopenvr.JOpenVRLibrary;
-import com.jme3.system.jopenvr.OpenVRUtil;
-import com.jme3.system.jopenvr.TrackedDevicePose_t;
-import com.jme3.system.jopenvr.VR_IVRCompositor_FnTable;
-import com.jme3.system.jopenvr.VR_IVRSystem_FnTable;
-import com.jme3.util.VRUtil;
-import com.sun.jna.Memory;
-import com.sun.jna.Pointer;
-import com.sun.jna.ptr.FloatByReference;
-import com.sun.jna.ptr.IntByReference;
-import com.sun.jna.ptr.LongByReference;
-
-import java.nio.IntBuffer;
-import java.util.Locale;
-import java.util.concurrent.TimeUnit;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * A class that wraps an OpenVR system.
- * @author reden - phr00t - https://github.com/phr00t
- * @author Julien Seinturier - (c) 2016 - JOrigin project - http:/www.jorigin.org
- */
-public class OpenVR implements VRAPI {
-
- private static final Logger logger = Logger.getLogger(OpenVR.class.getName());
-
- private static VR_IVRCompositor_FnTable compositorFunctions;
- private static VR_IVRSystem_FnTable vrsystemFunctions;
-
- private static boolean initSuccess = false;
- private static boolean flipEyes = false;
-
- private static IntBuffer hmdDisplayFrequency;
- private static TrackedDevicePose_t.ByReference hmdTrackedDevicePoseReference;
- protected static TrackedDevicePose_t[] hmdTrackedDevicePoses;
-
- protected static IntByReference hmdErrorStore;
-
- private static final Quaternion rotStore = new Quaternion();
- private static final Vector3f posStore = new Vector3f();
-
- private static FloatByReference tlastVsync;
-
- /**
- * The actual frame count.
- */
- public static LongByReference _tframeCount;
-
- // for debugging latency
- private int frames = 0;
-
- protected static Matrix4f[] poseMatrices;
-
- private static final Matrix4f hmdPose = Matrix4f.IDENTITY.clone();
- private static Matrix4f hmdProjectionLeftEye;
- private static Matrix4f hmdProjectionRightEye;
- private static Matrix4f hmdPoseLeftEye;
- private static Matrix4f hmdPoseRightEye;
-
- private static Vector3f hmdPoseLeftEyeVec, hmdPoseRightEyeVec, hmdSeatToStand;
-
- private static float vsyncToPhotons;
- private static double timePerFrame, frameCountRun;
- private static long frameCount;
- private static OpenVRInput VRinput;
-
- private VREnvironment environment = null;
-
- /**
- * Create a new OpenVR system
- * attached to the given {@link VREnvironment VR environment}.
- * @param environment the VR environment to which this API is attached.
- */
- public OpenVR(VREnvironment environment){
- this.environment = environment;
- }
-
- @Override
- public OpenVRInput getVRinput() {
- return VRinput;
- }
-
- @Override
- public VR_IVRSystem_FnTable getVRSystem() {
- return vrsystemFunctions;
- }
-
- @Override
- public VR_IVRCompositor_FnTable getCompositor() {
- return compositorFunctions;
- }
-
- @Override
- public String getName() {
- return "OpenVR";
- }
-
- private static long latencyWaitTime = 0;
-
- @Override
- public void setFlipEyes(boolean set) {
- flipEyes = set;
- }
-
- private boolean enableDebugLatency = false;
-
- @Override
- public void printLatencyInfoToConsole(boolean set) {
- enableDebugLatency = set;
- }
-
- @Override
- public int getDisplayFrequency() {
- if( hmdDisplayFrequency == null ) return 0;
- return hmdDisplayFrequency.get(0);
- }
-
- @Override
- public boolean initialize() {
-
- logger.config("Initializing OpenVR system...");
-
- hmdErrorStore = new IntByReference();
- vrsystemFunctions = null;
- JOpenVRLibrary.VR_InitInternal(hmdErrorStore, JOpenVRLibrary.EVRApplicationType.EVRApplicationType_VRApplication_Scene);
- if( hmdErrorStore.getValue() == 0 ) {
- vrsystemFunctions = new VR_IVRSystem_FnTable(JOpenVRLibrary.VR_GetGenericInterface(JOpenVRLibrary.IVRSystem_Version, hmdErrorStore).getPointer());
- }
-
- if( vrsystemFunctions == null || hmdErrorStore.getValue() != 0 ) {
- logger.severe("OpenVR Initialize Result: " + JOpenVRLibrary.VR_GetVRInitErrorAsEnglishDescription(hmdErrorStore.getValue()).getString(0));
- logger.severe("Initializing OpenVR system [FAILED]");
- return false;
- } else {
- logger.config("OpenVR initialized & VR connected.");
-
- vrsystemFunctions.setAutoSynch(false);
- vrsystemFunctions.read();
-
- tlastVsync = new FloatByReference();
- _tframeCount = new LongByReference();
-
- hmdDisplayFrequency = IntBuffer.allocate(1);
- hmdDisplayFrequency.put( (int) JOpenVRLibrary.ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayFrequency_Float);
- hmdTrackedDevicePoseReference = new TrackedDevicePose_t.ByReference();
- hmdTrackedDevicePoses = (TrackedDevicePose_t[])hmdTrackedDevicePoseReference.toArray(JOpenVRLibrary.k_unMaxTrackedDeviceCount);
- poseMatrices = new Matrix4f[JOpenVRLibrary.k_unMaxTrackedDeviceCount];
- for(int i=0;i 0 ) VRUtil.sleepNanos(latencyWaitTime);
-
- vrsystemFunctions.GetTimeSinceLastVsync.apply(tlastVsync, _tframeCount);
- float fSecondsUntilPhotons = (float)timePerFrame - tlastVsync.getValue() + vsyncToPhotons;
-
- if( enableDebugLatency ) {
- if( frames == 10 ) {
- System.out.println("Waited (nanos): " + Long.toString(latencyWaitTime));
- System.out.println("Predict ahead time: " + Float.toString(fSecondsUntilPhotons));
- }
- frames = (frames + 1) % 60;
- }
-
- // handle skipping frame stuff
- long nowCount = _tframeCount.getValue();
- if( nowCount - frameCount > 1 ) {
- // skipped a frame!
- if( enableDebugLatency ) System.out.println("Frame skipped!");
- frameCountRun = 0;
- if( latencyWaitTime > 0 ) {
- latencyWaitTime -= TimeUnit.MILLISECONDS.toNanos(1);
- if( latencyWaitTime < 0 ) latencyWaitTime = 0;
- }
- } else if( latencyWaitTime < timePerFrame * 1000000000.0 ) {
- // didn't skip a frame, lets try waiting longer to improve latency
- frameCountRun++;
- latencyWaitTime += Math.round(Math.pow(frameCountRun / 10.0, 2.0));
- }
-
- frameCount = nowCount;
-
- vrsystemFunctions.GetDeviceToAbsoluteTrackingPose.apply(
- environment.isSeatedExperience()?JOpenVRLibrary.ETrackingUniverseOrigin.ETrackingUniverseOrigin_TrackingUniverseSeated:
- JOpenVRLibrary.ETrackingUniverseOrigin.ETrackingUniverseOrigin_TrackingUniverseStanding,
- fSecondsUntilPhotons, hmdTrackedDevicePoseReference, JOpenVRLibrary.k_unMaxTrackedDeviceCount);
- }
-
- // deal with controllers being plugged in and out
- // causing an invalid memory crash... skipping for now
- /*boolean hasEvent = false;
- while( JOpenVRLibrary.VR_IVRSystem_PollNextEvent(OpenVR.getVRSystemInstance(), tempEvent) != 0 ) {
- // wait until the events are clear..
- hasEvent = true;
- }
- if( hasEvent ) {
- // an event probably changed controller state
- VRInput._updateConnectedControllers();
- }*/
- //update controllers pose information
- environment.getVRinput().updateControllerStates();
-
- // read pose data from native
- for (int nDevice = 0; nDevice < JOpenVRLibrary.k_unMaxTrackedDeviceCount; ++nDevice ){
- hmdTrackedDevicePoses[nDevice].readField("bPoseIsValid");
- if( hmdTrackedDevicePoses[nDevice].bPoseIsValid != 0 ){
- hmdTrackedDevicePoses[nDevice].readField("mDeviceToAbsoluteTracking");
- VRUtil.convertSteamVRMatrix3ToMatrix4f(hmdTrackedDevicePoses[nDevice].mDeviceToAbsoluteTracking, poseMatrices[nDevice]);
- }
- }
-
- if ( hmdTrackedDevicePoses[JOpenVRLibrary.k_unTrackedDeviceIndex_Hmd].bPoseIsValid != 0 ){
- hmdPose.set(poseMatrices[JOpenVRLibrary.k_unTrackedDeviceIndex_Hmd]);
- } else {
- hmdPose.set(Matrix4f.IDENTITY);
- }
- }
-
- @Override
- public Matrix4f getHMDMatrixProjectionLeftEye(Camera cam){
- if( hmdProjectionLeftEye != null ) {
- return hmdProjectionLeftEye;
- } else if(vrsystemFunctions == null){
- return cam.getProjectionMatrix();
- } else {
- HmdMatrix44_t mat = vrsystemFunctions.GetProjectionMatrix.apply(JOpenVRLibrary.EVREye.EVREye_Eye_Left, cam.getFrustumNear(), cam.getFrustumFar());
- hmdProjectionLeftEye = new Matrix4f();
- VRUtil.convertSteamVRMatrix4ToMatrix4f(mat, hmdProjectionLeftEye);
- return hmdProjectionLeftEye;
- }
- }
-
- @Override
- public Matrix4f getHMDMatrixProjectionRightEye(Camera cam){
- if( hmdProjectionRightEye != null ) {
- return hmdProjectionRightEye;
- } else if(vrsystemFunctions == null){
- return cam.getProjectionMatrix();
- } else {
- HmdMatrix44_t mat = vrsystemFunctions.GetProjectionMatrix.apply(JOpenVRLibrary.EVREye.EVREye_Eye_Right, cam.getFrustumNear(), cam.getFrustumFar());
- hmdProjectionRightEye = new Matrix4f();
- VRUtil.convertSteamVRMatrix4ToMatrix4f(mat, hmdProjectionRightEye);
- return hmdProjectionRightEye;
- }
- }
-
- @Override
- public Vector3f getHMDVectorPoseLeftEye() {
- if( hmdPoseLeftEyeVec == null ) {
- hmdPoseLeftEyeVec = getHMDMatrixPoseLeftEye().toTranslationVector();
- // set default IPD if none or broken
- if( hmdPoseLeftEyeVec.x <= 0.080f * -0.5f || hmdPoseLeftEyeVec.x >= 0.040f * -0.5f ) {
- 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 = getHMDMatrixPoseRightEye().toTranslationVector();
- // set default IPD if none or broken
- if( hmdPoseRightEyeVec.x >= 0.080f * 0.5f || hmdPoseRightEyeVec.x <= 0.040f * 0.5f ) {
- hmdPoseRightEyeVec.x = 0.065f * 0.5f;
- }
- if( flipEyes == false ) hmdPoseRightEyeVec.x *= -1f; // it seems these need flipping
- }
- return hmdPoseRightEyeVec;
- }
-
- @Override
- public Vector3f getSeatedToAbsolutePosition() {
- if( environment.isSeatedExperience() == false ) return Vector3f.ZERO;
- if( hmdSeatToStand == null ) {
- hmdSeatToStand = new Vector3f();
- HmdMatrix34_t mat = vrsystemFunctions.GetSeatedZeroPoseToStandingAbsoluteTrackingPose.apply();
- Matrix4f tempmat = new Matrix4f();
- VRUtil.convertSteamVRMatrix3ToMatrix4f(mat, tempmat);
- tempmat.toTranslationVector(hmdSeatToStand);
- }
- return hmdSeatToStand;
- }
-
- @Override
- public Matrix4f getHMDMatrixPoseLeftEye(){
- if( hmdPoseLeftEye != null ) {
- return hmdPoseLeftEye;
- } else if(vrsystemFunctions == null) {
- return Matrix4f.IDENTITY;
- } else {
- HmdMatrix34_t mat = vrsystemFunctions.GetEyeToHeadTransform.apply(JOpenVRLibrary.EVREye.EVREye_Eye_Left);
- hmdPoseLeftEye = new Matrix4f();
- return VRUtil.convertSteamVRMatrix3ToMatrix4f(mat, hmdPoseLeftEye);
- }
- }
-
- @Override
- public HmdType getType() {
- if( vrsystemFunctions != null ) {
- Pointer str1 = new Memory(128);
- Pointer str2 = new Memory(128);
- String completeName = "";
- vrsystemFunctions.GetStringTrackedDeviceProperty.apply(JOpenVRLibrary.k_unTrackedDeviceIndex_Hmd,
- JOpenVRLibrary.ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_ManufacturerName_String,
- str1, 128, hmdErrorStore);
- if( hmdErrorStore.getValue() == 0 ) completeName += str1.getString(0);
- vrsystemFunctions.GetStringTrackedDeviceProperty.apply(JOpenVRLibrary.k_unTrackedDeviceIndex_Hmd,
- JOpenVRLibrary.ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_ModelNumber_String,
- str2, 128, hmdErrorStore);
- if( hmdErrorStore.getValue() == 0 ) completeName += " " + str2.getString(0);
- if( completeName.length() > 0 ) {
- completeName = completeName.toLowerCase(Locale.ENGLISH).trim();
- if( completeName.contains("htc") || completeName.contains("vive") ) {
- return HmdType.HTC_VIVE;
- } else if( completeName.contains("osvr") ) {
- return HmdType.OSVR;
- } else if( completeName.contains("oculus") || completeName.contains("rift") ||
- completeName.contains("dk1") || completeName.contains("dk2") || completeName.contains("cv1") ) {
- return HmdType.OCULUS_RIFT;
- } else if( completeName.contains("fove") ) {
- return HmdType.FOVE;
- } else if( completeName.contains("game") && completeName.contains("face") ) {
- return HmdType.GAMEFACE;
- } else if( completeName.contains("morpheus") ) {
- return HmdType.MORPHEUS;
- } else if( completeName.contains("gear") ) {
- return HmdType.GEARVR;
- } else if( completeName.contains("star") ) {
- return HmdType.STARVR;
- } else if( completeName.contains("null") ) {
- return HmdType.NULL;
- }
- }
- } else return HmdType.NONE;
- return HmdType.OTHER;
- }
-
- @Override
- public Matrix4f getHMDMatrixPoseRightEye(){
- if( hmdPoseRightEye != null ) {
- return hmdPoseRightEye;
- } else if(vrsystemFunctions == null) {
- return Matrix4f.IDENTITY;
- } else {
- HmdMatrix34_t mat = vrsystemFunctions.GetEyeToHeadTransform.apply(JOpenVRLibrary.EVREye.EVREye_Eye_Right);
- hmdPoseRightEye = new Matrix4f();
- return VRUtil.convertSteamVRMatrix3ToMatrix4f(mat, hmdPoseRightEye);
- }
- }
-
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+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.jopenvr.HmdMatrix34_t;
+import com.jme3.system.jopenvr.HmdMatrix44_t;
+import com.jme3.system.jopenvr.JOpenVRLibrary;
+import com.jme3.system.jopenvr.OpenVRUtil;
+import com.jme3.system.jopenvr.TrackedDevicePose_t;
+import com.jme3.system.jopenvr.VR_IVRCompositor_FnTable;
+import com.jme3.system.jopenvr.VR_IVRSystem_FnTable;
+import com.jme3.util.VRUtil;
+import com.sun.jna.Memory;
+import com.sun.jna.Pointer;
+import com.sun.jna.ptr.FloatByReference;
+import com.sun.jna.ptr.IntByReference;
+import com.sun.jna.ptr.LongByReference;
+
+import java.nio.IntBuffer;
+import java.util.Locale;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * A class that wraps an OpenVR system.
+ * @author reden - phr00t - https://github.com/phr00t
+ * @author Julien Seinturier - (c) 2016 - JOrigin project - http:/www.jorigin.org
+ */
+public class OpenVR implements VRAPI {
+
+ private static final Logger logger = Logger.getLogger(OpenVR.class.getName());
+
+ private static VR_IVRCompositor_FnTable compositorFunctions;
+ private static VR_IVRSystem_FnTable vrsystemFunctions;
+
+ private static boolean initSuccess = false;
+ private static boolean flipEyes = false;
+
+ private IntBuffer hmdDisplayFrequency;
+ private TrackedDevicePose_t.ByReference hmdTrackedDevicePoseReference;
+ protected TrackedDevicePose_t[] hmdTrackedDevicePoses;
+
+ protected IntByReference hmdErrorStore;
+
+ private final Quaternion rotStore = new Quaternion();
+ private final Vector3f posStore = new Vector3f();
+
+ private static FloatByReference tlastVsync;
+
+ /**
+ * The actual frame count.
+ */
+ public static LongByReference _tframeCount;
+
+ // for debugging latency
+ private int frames = 0;
+
+ protected Matrix4f[] poseMatrices;
+
+ private final Matrix4f hmdPose = Matrix4f.IDENTITY.clone();
+ private Matrix4f hmdProjectionLeftEye;
+ private Matrix4f hmdProjectionRightEye;
+ private Matrix4f hmdPoseLeftEye;
+ private Matrix4f hmdPoseRightEye;
+
+ private Vector3f hmdPoseLeftEyeVec, hmdPoseRightEyeVec, hmdSeatToStand;
+
+ private float vsyncToPhotons;
+ private double timePerFrame, frameCountRun;
+ private long frameCount;
+ private OpenVRInput VRinput;
+
+
+ private VREnvironment environment = null;
+
+ /**
+ * Create a new OpenVR system
+ * attached to the given {@link VREnvironment VR environment}.
+ * @param environment the VR environment to which this API is attached.
+ */
+ public OpenVR(VREnvironment environment){
+ this.environment = environment;
+ }
+
+ @Override
+ public OpenVRInput getVRinput() {
+ return VRinput;
+ }
+
+ @Override
+ public VR_IVRSystem_FnTable getVRSystem() {
+ return vrsystemFunctions;
+ }
+
+ @Override
+ public VR_IVRCompositor_FnTable getCompositor() {
+ return compositorFunctions;
+ }
+
+ @Override
+ public String getName() {
+ return "OpenVR";
+ }
+
+ private static long latencyWaitTime = 0;
+
+ @Override
+ public void setFlipEyes(boolean set) {
+ flipEyes = set;
+ }
+
+ private boolean enableDebugLatency = false;
+
+ @Override
+ public void printLatencyInfoToConsole(boolean set) {
+ enableDebugLatency = set;
+ }
+
+ @Override
+ public int getDisplayFrequency() {
+ if( hmdDisplayFrequency == null ) return 0;
+ return hmdDisplayFrequency.get(0);
+ }
+
+ @Override
+ public boolean initialize() {
+
+ logger.config("Initializing OpenVR system...");
+
+ hmdErrorStore = new IntByReference();
+ vrsystemFunctions = null;
+ JOpenVRLibrary.VR_InitInternal(hmdErrorStore, JOpenVRLibrary.EVRApplicationType.EVRApplicationType_VRApplication_Scene);
+ if( hmdErrorStore.getValue() == 0 ) {
+ vrsystemFunctions = new VR_IVRSystem_FnTable(JOpenVRLibrary.VR_GetGenericInterface(JOpenVRLibrary.IVRSystem_Version, hmdErrorStore).getPointer());
+ }
+
+ if( vrsystemFunctions == null || hmdErrorStore.getValue() != 0 ) {
+ logger.severe("OpenVR Initialize Result: " + JOpenVRLibrary.VR_GetVRInitErrorAsEnglishDescription(hmdErrorStore.getValue()).getString(0));
+ logger.severe("Initializing OpenVR system [FAILED]");
+ return false;
+ } else {
+ logger.config("OpenVR initialized & VR connected.");
+
+ vrsystemFunctions.setAutoSynch(false);
+ vrsystemFunctions.read();
+
+ tlastVsync = new FloatByReference();
+ _tframeCount = new LongByReference();
+
+ hmdDisplayFrequency = IntBuffer.allocate(1);
+ hmdDisplayFrequency.put( (int) JOpenVRLibrary.ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayFrequency_Float);
+ hmdTrackedDevicePoseReference = new TrackedDevicePose_t.ByReference();
+ hmdTrackedDevicePoses = (TrackedDevicePose_t[])hmdTrackedDevicePoseReference.toArray(JOpenVRLibrary.k_unMaxTrackedDeviceCount);
+ poseMatrices = new Matrix4f[JOpenVRLibrary.k_unMaxTrackedDeviceCount];
+ for(int i=0;i 0 ) VRUtil.sleepNanos(latencyWaitTime);
+
+ vrsystemFunctions.GetTimeSinceLastVsync.apply(tlastVsync, _tframeCount);
+ float fSecondsUntilPhotons = (float)timePerFrame - tlastVsync.getValue() + vsyncToPhotons;
+
+ if( enableDebugLatency ) {
+ if( frames == 10 ) {
+ System.out.println("Waited (nanos): " + Long.toString(latencyWaitTime));
+ System.out.println("Predict ahead time: " + Float.toString(fSecondsUntilPhotons));
+ }
+ frames = (frames + 1) % 60;
+ }
+
+ // handle skipping frame stuff
+ long nowCount = _tframeCount.getValue();
+ if( nowCount - frameCount > 1 ) {
+ // skipped a frame!
+ if( enableDebugLatency ) System.out.println("Frame skipped!");
+ frameCountRun = 0;
+ if( latencyWaitTime > 0 ) {
+ latencyWaitTime -= TimeUnit.MILLISECONDS.toNanos(1);
+ if( latencyWaitTime < 0 ) latencyWaitTime = 0;
+ }
+ } else if( latencyWaitTime < timePerFrame * 1000000000.0 ) {
+ // didn't skip a frame, lets try waiting longer to improve latency
+ frameCountRun++;
+ latencyWaitTime += Math.round(Math.pow(frameCountRun / 10.0, 2.0));
+ }
+
+ frameCount = nowCount;
+
+ vrsystemFunctions.GetDeviceToAbsoluteTrackingPose.apply(
+ environment.isSeatedExperience()?JOpenVRLibrary.ETrackingUniverseOrigin.ETrackingUniverseOrigin_TrackingUniverseSeated:
+ JOpenVRLibrary.ETrackingUniverseOrigin.ETrackingUniverseOrigin_TrackingUniverseStanding,
+ fSecondsUntilPhotons, hmdTrackedDevicePoseReference, JOpenVRLibrary.k_unMaxTrackedDeviceCount);
+ }
+
+ // deal with controllers being plugged in and out
+ // causing an invalid memory crash... skipping for now
+ /*boolean hasEvent = false;
+ while( JOpenVRLibrary.VR_IVRSystem_PollNextEvent(OpenVR.getVRSystemInstance(), tempEvent) != 0 ) {
+ // wait until the events are clear..
+ hasEvent = true;
+ }
+ if( hasEvent ) {
+ // an event probably changed controller state
+ VRInput._updateConnectedControllers();
+ }*/
+ //update controllers pose information
+ environment.getVRinput().updateControllerStates();
+
+ // read pose data from native
+ for (int nDevice = 0; nDevice < JOpenVRLibrary.k_unMaxTrackedDeviceCount; ++nDevice ){
+ hmdTrackedDevicePoses[nDevice].readField("bPoseIsValid");
+ if( hmdTrackedDevicePoses[nDevice].bPoseIsValid != 0 ){
+ hmdTrackedDevicePoses[nDevice].readField("mDeviceToAbsoluteTracking");
+ VRUtil.convertSteamVRMatrix3ToMatrix4f(hmdTrackedDevicePoses[nDevice].mDeviceToAbsoluteTracking, poseMatrices[nDevice]);
+ }
+ }
+
+ if ( hmdTrackedDevicePoses[JOpenVRLibrary.k_unTrackedDeviceIndex_Hmd].bPoseIsValid != 0 ){
+ hmdPose.set(poseMatrices[JOpenVRLibrary.k_unTrackedDeviceIndex_Hmd]);
+ } else {
+ hmdPose.set(Matrix4f.IDENTITY);
+ }
+ }
+
+ @Override
+ public Matrix4f getHMDMatrixProjectionLeftEye(Camera cam){
+ if( hmdProjectionLeftEye != null ) {
+ return hmdProjectionLeftEye;
+ } else if(vrsystemFunctions == null){
+ return cam.getProjectionMatrix();
+ } else {
+ HmdMatrix44_t mat = vrsystemFunctions.GetProjectionMatrix.apply(JOpenVRLibrary.EVREye.EVREye_Eye_Left, cam.getFrustumNear(), cam.getFrustumFar());
+ hmdProjectionLeftEye = new Matrix4f();
+ VRUtil.convertSteamVRMatrix4ToMatrix4f(mat, hmdProjectionLeftEye);
+ return hmdProjectionLeftEye;
+ }
+ }
+
+ @Override
+ public Matrix4f getHMDMatrixProjectionRightEye(Camera cam){
+ if( hmdProjectionRightEye != null ) {
+ return hmdProjectionRightEye;
+ } else if(vrsystemFunctions == null){
+ return cam.getProjectionMatrix();
+ } else {
+ HmdMatrix44_t mat = vrsystemFunctions.GetProjectionMatrix.apply(JOpenVRLibrary.EVREye.EVREye_Eye_Right, cam.getFrustumNear(), cam.getFrustumFar());
+ hmdProjectionRightEye = new Matrix4f();
+ VRUtil.convertSteamVRMatrix4ToMatrix4f(mat, hmdProjectionRightEye);
+ return hmdProjectionRightEye;
+ }
+ }
+
+ @Override
+ public Vector3f getHMDVectorPoseLeftEye() {
+ if( hmdPoseLeftEyeVec == null ) {
+ hmdPoseLeftEyeVec = getHMDMatrixPoseLeftEye().toTranslationVector();
+ // set default IPD if none or broken
+ if( hmdPoseLeftEyeVec.x <= 0.080f * -0.5f || hmdPoseLeftEyeVec.x >= 0.040f * -0.5f ) {
+ 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 = getHMDMatrixPoseRightEye().toTranslationVector();
+ // set default IPD if none or broken
+ if( hmdPoseRightEyeVec.x >= 0.080f * 0.5f || hmdPoseRightEyeVec.x <= 0.040f * 0.5f ) {
+ hmdPoseRightEyeVec.x = 0.065f * 0.5f;
+ }
+ if( flipEyes == false ) hmdPoseRightEyeVec.x *= -1f; // it seems these need flipping
+ }
+ return hmdPoseRightEyeVec;
+ }
+
+ @Override
+ public Vector3f getSeatedToAbsolutePosition() {
+ if( environment.isSeatedExperience() == false ) return Vector3f.ZERO;
+ if( hmdSeatToStand == null ) {
+ hmdSeatToStand = new Vector3f();
+ HmdMatrix34_t mat = vrsystemFunctions.GetSeatedZeroPoseToStandingAbsoluteTrackingPose.apply();
+ Matrix4f tempmat = new Matrix4f();
+ VRUtil.convertSteamVRMatrix3ToMatrix4f(mat, tempmat);
+ tempmat.toTranslationVector(hmdSeatToStand);
+ }
+ return hmdSeatToStand;
+ }
+
+ @Override
+ public Matrix4f getHMDMatrixPoseLeftEye(){
+ if( hmdPoseLeftEye != null ) {
+ return hmdPoseLeftEye;
+ } else if(vrsystemFunctions == null) {
+ return Matrix4f.IDENTITY;
+ } else {
+ HmdMatrix34_t mat = vrsystemFunctions.GetEyeToHeadTransform.apply(JOpenVRLibrary.EVREye.EVREye_Eye_Left);
+ hmdPoseLeftEye = new Matrix4f();
+ return VRUtil.convertSteamVRMatrix3ToMatrix4f(mat, hmdPoseLeftEye);
+ }
+ }
+
+ @Override
+ public HmdType getType() {
+ if( vrsystemFunctions != null ) {
+ Pointer str1 = new Memory(128);
+ Pointer str2 = new Memory(128);
+ String completeName = "";
+ vrsystemFunctions.GetStringTrackedDeviceProperty.apply(JOpenVRLibrary.k_unTrackedDeviceIndex_Hmd,
+ JOpenVRLibrary.ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_ManufacturerName_String,
+ str1, 128, hmdErrorStore);
+ if( hmdErrorStore.getValue() == 0 ) completeName += str1.getString(0);
+ vrsystemFunctions.GetStringTrackedDeviceProperty.apply(JOpenVRLibrary.k_unTrackedDeviceIndex_Hmd,
+ JOpenVRLibrary.ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_ModelNumber_String,
+ str2, 128, hmdErrorStore);
+ if( hmdErrorStore.getValue() == 0 ) completeName += " " + str2.getString(0);
+ if( completeName.length() > 0 ) {
+ completeName = completeName.toLowerCase(Locale.ENGLISH).trim();
+ if( completeName.contains("htc") || completeName.contains("vive") ) {
+ return HmdType.HTC_VIVE;
+ } else if( completeName.contains("osvr") ) {
+ return HmdType.OSVR;
+ } else if( completeName.contains("oculus") || completeName.contains("rift") ||
+ completeName.contains("dk1") || completeName.contains("dk2") || completeName.contains("cv1") ) {
+ return HmdType.OCULUS_RIFT;
+ } else if( completeName.contains("fove") ) {
+ return HmdType.FOVE;
+ } else if( completeName.contains("game") && completeName.contains("face") ) {
+ return HmdType.GAMEFACE;
+ } else if( completeName.contains("morpheus") ) {
+ return HmdType.MORPHEUS;
+ } else if( completeName.contains("gear") ) {
+ return HmdType.GEARVR;
+ } else if( completeName.contains("star") ) {
+ return HmdType.STARVR;
+ } else if( completeName.contains("null") ) {
+ return HmdType.NULL;
+ }
+ }
+ } else return HmdType.NONE;
+ return HmdType.OTHER;
+ }
+
+ @Override
+ public Matrix4f getHMDMatrixPoseRightEye(){
+ if( hmdPoseRightEye != null ) {
+ return hmdPoseRightEye;
+ } else if(vrsystemFunctions == null) {
+ return Matrix4f.IDENTITY;
+ } else {
+ HmdMatrix34_t mat = vrsystemFunctions.GetEyeToHeadTransform.apply(JOpenVRLibrary.EVREye.EVREye_Eye_Right);
+ hmdPoseRightEye = new Matrix4f();
+ return VRUtil.convertSteamVRMatrix3ToMatrix4f(mat, hmdPoseRightEye);
+ }
+ }
+
+}
diff --git a/jme3-vr/src/main/java/com/jme3/input/vr/OpenVRInput.java b/jme3-vr/src/main/java/com/jme3/input/vr/OpenVRInput.java
index b4b5cdce5..2f9b81e95 100644
--- a/jme3-vr/src/main/java/com/jme3/input/vr/OpenVRInput.java
+++ b/jme3-vr/src/main/java/com/jme3/input/vr/OpenVRInput.java
@@ -5,6 +5,7 @@
*/
package com.jme3.input.vr;
+import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -183,28 +184,50 @@ public class OpenVRInput implements VRInputAPI {
@Override
public Vector3f getVelocity(int controllerIndex) {
- int index = OpenVRInput.controllerIndex[controllerIndex];
- if( needsNewVelocity[index] ) {
- OpenVR.hmdTrackedDevicePoses[index].readField("vVelocity");
- needsNewVelocity[index] = false;
- }
- tempVel.x = OpenVR.hmdTrackedDevicePoses[index].vVelocity.v[0];
- tempVel.y = OpenVR.hmdTrackedDevicePoses[index].vVelocity.v[1];
- tempVel.z = OpenVR.hmdTrackedDevicePoses[index].vVelocity.v[2];
- return tempVel;
+
+ if (environment != null){
+
+ if (environment.getVRHardware() instanceof OpenVR){
+ int index = OpenVRInput.controllerIndex[controllerIndex];
+ if( needsNewVelocity[index] ) {
+ ((OpenVR)environment.getVRHardware()).hmdTrackedDevicePoses[index].readField("vVelocity");
+ needsNewVelocity[index] = false;
+ }
+ tempVel.x = ((OpenVR)environment.getVRHardware()).hmdTrackedDevicePoses[index].vVelocity.v[0];
+ tempVel.y = ((OpenVR)environment.getVRHardware()).hmdTrackedDevicePoses[index].vVelocity.v[1];
+ tempVel.z = ((OpenVR)environment.getVRHardware()).hmdTrackedDevicePoses[index].vVelocity.v[2];
+ return tempVel;
+ } else {
+ throw new IllegalStateException("VR hardware "+environment.getVRHardware().getClass().getSimpleName()+" is not a subclass of "+OpenVR.class.getSimpleName());
+ }
+ } else {
+ throw new IllegalStateException("VR input is not attached to a VR environment.");
+ }
}
@Override
public Vector3f getAngularVelocity(int controllerIndex) {
- int index = OpenVRInput.controllerIndex[controllerIndex];
- if( needsNewAngVelocity[index] ) {
- OpenVR.hmdTrackedDevicePoses[index].readField("vAngularVelocity");
- needsNewAngVelocity[index] = false;
- }
- tempVel.x = OpenVR.hmdTrackedDevicePoses[index].vAngularVelocity.v[0];
- tempVel.y = OpenVR.hmdTrackedDevicePoses[index].vAngularVelocity.v[1];
- tempVel.z = OpenVR.hmdTrackedDevicePoses[index].vAngularVelocity.v[2];
- return tempVel;
+
+ if (environment != null){
+
+ if (environment.getVRHardware() instanceof OpenVR){
+
+ int index = OpenVRInput.controllerIndex[controllerIndex];
+ if( needsNewAngVelocity[index] ) {
+ ((OpenVR)environment.getVRHardware()).hmdTrackedDevicePoses[index].readField("vAngularVelocity");
+ needsNewAngVelocity[index] = false;
+ }
+ tempVel.x = ((OpenVR)environment.getVRHardware()).hmdTrackedDevicePoses[index].vAngularVelocity.v[0];
+ tempVel.y = ((OpenVR)environment.getVRHardware()).hmdTrackedDevicePoses[index].vAngularVelocity.v[1];
+ tempVel.z = ((OpenVR)environment.getVRHardware()).hmdTrackedDevicePoses[index].vAngularVelocity.v[2];
+ return tempVel;
+ } else {
+ throw new IllegalStateException("VR hardware "+environment.getVRHardware().getClass().getSimpleName()+" is not a subclass of "+OpenVR.class.getSimpleName());
+ }
+ } else {
+ throw new IllegalStateException("VR input is not attached to a VR environment.");
+ }
+
}
@Override
@@ -309,7 +332,16 @@ public class OpenVRInput implements VRInputAPI {
return false;
}
- return OpenVR.hmdTrackedDevicePoses[controllerIndex[index]].bPoseIsValid != 0;
+ if (environment != null){
+
+ if (environment.getVRHardware() instanceof OpenVR){
+ return ((OpenVR)environment.getVRHardware()).hmdTrackedDevicePoses[controllerIndex[index]].bPoseIsValid != 0;
+ } else {
+ throw new IllegalStateException("VR hardware "+environment.getVRHardware().getClass().getSimpleName()+" is not a subclass of "+OpenVR.class.getSimpleName());
+ }
+ } else {
+ throw new IllegalStateException("VR input is not attached to a VR environment.");
+ }
}
@Override
@@ -317,9 +349,19 @@ public class OpenVRInput implements VRInputAPI {
if( isInputDeviceTracking(index) == false ){
return null;
}
- index = controllerIndex[index];
- VRUtil.convertMatrix4toQuat(OpenVR.poseMatrices[index], rotStore[index]);
- return rotStore[index];
+
+ if (environment != null){
+
+ if (environment.getVRHardware() instanceof OpenVR){
+ index = controllerIndex[index];
+ VRUtil.convertMatrix4toQuat(((OpenVR)environment.getVRHardware()).poseMatrices[index], rotStore[index]);
+ return rotStore[index];
+ } else {
+ throw new IllegalStateException("VR hardware "+environment.getVRHardware().getClass().getSimpleName()+" is not a subclass of "+OpenVR.class.getSimpleName());
+ }
+ } else {
+ throw new IllegalStateException("VR input is not attached to a VR environment.");
+ }
}
@Override
@@ -328,12 +370,23 @@ public class OpenVRInput implements VRInputAPI {
return null;
}
- // the hmdPose comes in rotated funny, fix that here
- index = controllerIndex[index];
- OpenVR.poseMatrices[index].toTranslationVector(posStore[index]);
- posStore[index].x = -posStore[index].x;
- posStore[index].z = -posStore[index].z;
- return posStore[index];
+ if (environment != null){
+
+ if (environment.getVRHardware() instanceof OpenVR){
+ // the hmdPose comes in rotated funny, fix that here
+ index = controllerIndex[index];
+ ((OpenVR)environment.getVRHardware()).poseMatrices[index].toTranslationVector(posStore[index]);
+ posStore[index].x = -posStore[index].x;
+ posStore[index].z = -posStore[index].z;
+ return posStore[index];
+ } else {
+ throw new IllegalStateException("VR hardware "+environment.getVRHardware().getClass().getSimpleName()+" is not a subclass of "+OpenVR.class.getSimpleName());
+ }
+ } else {
+ throw new IllegalStateException("VR input is not attached to a VR environment.");
+ }
+
+
}
@Override
@@ -411,9 +464,9 @@ public class OpenVRInput implements VRInputAPI {
if (environment != null){
controllerCount = 0;
for(int i=0;i(JOpenVRLibrary.k_unMaxTrackedDeviceCount);
+ }
+ trackedControllers.add(new OpenVRTrackedController(i, this, controllerName, manufacturerName, environment));
+
// Send an Haptic pulse to the controller
triggerHapticPulse(controllerCount, 1.0f);
diff --git a/jme3-vr/src/main/java/com/jme3/input/vr/OpenVRTrackedController.java b/jme3-vr/src/main/java/com/jme3/input/vr/OpenVRTrackedController.java
new file mode 100644
index 000000000..026830604
--- /dev/null
+++ b/jme3-vr/src/main/java/com/jme3/input/vr/OpenVRTrackedController.java
@@ -0,0 +1,93 @@
+package com.jme3.input.vr;
+
+import com.jme3.app.VREnvironment;
+import com.jme3.math.Matrix4f;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Vector3f;
+
+public class OpenVRTrackedController implements VRTrackedController{
+
+ /**
+ * The index of the controller within the unserlying VR API.
+ */
+ private int controllerIndex = -1;
+
+ /**
+ * The underlying VRAPI.
+ */
+ private OpenVRInput hardware = null;
+
+ /**
+ * The name of the controller.
+ */
+ private String name;
+
+ private VREnvironment environment;
+
+ /**
+ * Wrap a new VR tracked controller on an OpenVR system.
+ * @param controllerIndex the index of the controller within the underlying VR system.
+ * @param hardware the underlying VR system.
+ * @param name the name of the controller.
+ * @param manufacturer the manufacturer of the controller.
+ * @param environment the VR environment.
+ */
+ public OpenVRTrackedController(int controllerIndex, OpenVRInput hardware, String name, String manufacturer, VREnvironment environment){
+ this.controllerIndex = controllerIndex;
+ this.hardware = hardware;
+
+ this.name = name;
+ this.manufacturer = manufacturer;
+
+ this.environment = environment;
+ }
+
+ /**
+ * The manufacturer of the controller.
+ */
+ private String manufacturer;
+
+ @Override
+ public Vector3f getPosition() {
+ if (hardware != null){
+ return hardware.getPosition(controllerIndex);
+ } else {
+ throw new IllegalStateException("No underlying VR API.");
+ }
+ }
+
+ @Override
+ public Quaternion getOrientation() {
+ if (hardware != null){
+ return hardware.getOrientation(controllerIndex);
+ } else {
+ throw new IllegalStateException("No underlying VR API.");
+ }
+ }
+
+ @Override
+ public Matrix4f getPose(){
+
+ if (environment != null){
+ if (hardware != null){
+ return ((OpenVR)environment.getVRHardware()).poseMatrices[controllerIndex];
+ } else {
+ throw new IllegalStateException("No underlying VR API.");
+ }
+ } else {
+ throw new IllegalStateException("VR tracked device is not attached to any environment.");
+ }
+
+
+ }
+
+ @Override
+ public String getControllerName() {
+ return name;
+ }
+
+ @Override
+ public String getControllerManufacturer() {
+ return manufacturer;
+ }
+}
diff --git a/jme3-vr/src/main/java/com/jme3/input/vr/VRBounds.java b/jme3-vr/src/main/java/com/jme3/input/vr/VRBounds.java
index 15ce659ea..0f81b4105 100644
--- a/jme3-vr/src/main/java/com/jme3/input/vr/VRBounds.java
+++ b/jme3-vr/src/main/java/com/jme3/input/vr/VRBounds.java
@@ -16,19 +16,19 @@ public class VRBounds {
private static Logger logger = Logger.getLogger(VRBounds.class.getName());
- private static VR_IVRChaperone_FnTable vrChaperone;
- private static Vector2f playSize;
+ private VR_IVRChaperone_FnTable vrChaperone;
+ private Vector2f playSize;
/**
* Initialize the VR bounds.
* @return true
if the initialization is a success and false
otherwise.
*/
- public static boolean init() {
+ public boolean init(OpenVR api) {
logger.config("Initialize VR bounds...");
if( vrChaperone == null ) {
- vrChaperone = new VR_IVRChaperone_FnTable(JOpenVRLibrary.VR_GetGenericInterface(JOpenVRLibrary.IVRChaperone_Version, OpenVR.hmdErrorStore).getPointer());
+ vrChaperone = new VR_IVRChaperone_FnTable(JOpenVRLibrary.VR_GetGenericInterface(JOpenVRLibrary.IVRChaperone_Version, api.hmdErrorStore).getPointer());
if( vrChaperone != null ) {
vrChaperone.setAutoSynch(false);
vrChaperone.read();
@@ -53,7 +53,7 @@ public class VRBounds {
* Get the size of the VR world.
* @return the size of the VR world.
*/
- public static Vector2f getPlaySize() {
+ public Vector2f getPlaySize() {
return playSize;
}
diff --git a/jme3-vr/src/main/java/com/jme3/input/vr/VRTrackedController.java b/jme3-vr/src/main/java/com/jme3/input/vr/VRTrackedController.java
index 5fb2572a0..3ce20e5c0 100644
--- a/jme3-vr/src/main/java/com/jme3/input/vr/VRTrackedController.java
+++ b/jme3-vr/src/main/java/com/jme3/input/vr/VRTrackedController.java
@@ -1,5 +1,9 @@
package com.jme3.input.vr;
+import com.jme3.math.Matrix4f;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Vector3f;
+
/**
* TODO
* @author Julien Seinturier - (c) 2016 - JOrigin project - http:/www.jorigin.org
@@ -7,4 +11,40 @@ package com.jme3.input.vr;
*/
public interface VRTrackedController {
+ /**
+ * Get the controller name.
+ * @return the controller name.
+ */
+ public String getControllerName();
+
+ /**
+ * Get the controller manufacturer.
+ * @return the controller manufacturer.
+ */
+ public String getControllerManufacturer();
+
+ /**
+ * Get the position of the tracked device. This value is the translation component of the device {@link #getPose() pose}.
+ * @return the position of the tracked device.
+ * @see #getOrientation()
+ * @see #getPose()
+ */
+ public Vector3f getPosition();
+
+ /**
+ * Get the orientation of the tracked device. This value is the rotation component of the device {@link #getPose() pose}.
+ * @return the orientation of the tracked device.
+ * @see #getPosition()
+ * @see #getPose()
+ */
+ public Quaternion getOrientation();
+
+ /**
+ * Get the pose of the tracked device.
+ * The pose is a 4x4 matrix than combine the {@link #getPosition() position} and the {@link #getOrientation() orientation} of the device.
+ * @return the pose of the tracked device.
+ * @see #getPosition()
+ * @see #getOrientation()
+ */
+ public Matrix4f getPose();
}
diff --git a/jme3-vr/src/main/java/com/jme3/util/AbstractVRViewManager.java b/jme3-vr/src/main/java/com/jme3/util/AbstractVRViewManager.java
index 7a9b5ea56..f4f7e7f91 100644
--- a/jme3-vr/src/main/java/com/jme3/util/AbstractVRViewManager.java
+++ b/jme3-vr/src/main/java/com/jme3/util/AbstractVRViewManager.java
@@ -28,18 +28,20 @@ public abstract class AbstractVRViewManager implements VRViewManager {
protected VREnvironment environment = null;
protected Camera leftCamera;
- protected ViewPort leftViewport;
+ protected ViewPort leftViewPort;
protected FilterPostProcessor leftPostProcessor;
protected Texture2D leftEyeTexture;
protected Texture2D leftEyeDepth;
protected Camera rightCamera;
- protected ViewPort rightViewport;
+ protected ViewPort rightViewPort;
protected FilterPostProcessor rightPostProcessor;
protected Texture2D rightEyeTexture;
protected Texture2D rightEyeDepth;
- private float resMult = 1f;
+ protected ViewPort mirrorViewPort;
+
+ private float resMult = 1f;
private float heightAdjustment;
@@ -54,15 +56,24 @@ public abstract class AbstractVRViewManager implements VRViewManager {
}
@Override
- public ViewPort getLeftViewport() {
- return leftViewport;
+ public ViewPort getLeftViewPort() {
+ return leftViewPort;
}
@Override
- public ViewPort getRightViewport() {
- return rightViewport;
+ public ViewPort getRightViewPort() {
+ return rightViewPort;
}
+ /**
+ * Get the {@link ViewPort view port} attached to the mirror display.
+ * @return the view port attached to the mirror display.
+ */
+ public ViewPort getMirrorViewPort() {
+ return mirrorViewPort;
+ }
+
+
@Override
public Texture2D getLeftTexture(){
return leftEyeTexture;
@@ -124,7 +135,7 @@ public abstract class AbstractVRViewManager implements VRViewManager {
public void moveScreenProcessingToEyes() {
if (environment != null){
- if( getRightViewport() == null ){
+ if( getRightViewPort() == null ){
return;
}
@@ -150,7 +161,7 @@ public abstract class AbstractVRViewManager implements VRViewManager {
public void syncScreenProcessing(ViewPort sourceViewport) {
if (environment != null){
- if( getRightViewport() == null ){
+ if( getRightViewPort() == null ){
return;
}
@@ -163,13 +174,13 @@ public abstract class AbstractVRViewManager implements VRViewManager {
// clear out all filters & processors, to start from scratch
getRightPostProcessor().removeAllFilters();
getLeftPostProcessor().removeAllFilters();
- getLeftViewport().clearProcessors();
- getRightViewport().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
- getLeftViewport().addProcessor(getLeftPostProcessor());
- getRightViewport().addProcessor(getRightPostProcessor());
+ getLeftViewPort().addProcessor(getLeftPostProcessor());
+ getRightViewPort().addProcessor(getRightPostProcessor());
// 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()) {
@@ -202,8 +213,8 @@ public abstract class AbstractVRViewManager implements VRViewManager {
VRDirectionalLightShadowRenderer dlsr = (VRDirectionalLightShadowRenderer) sceneProcessor;
VRDirectionalLightShadowRenderer dlsrRight = dlsr.clone();
dlsrRight.setLight(dlsr.getLight());
- getRightViewport().getProcessors().add(0, dlsrRight);
- getLeftViewport().getProcessors().add(0, sceneProcessor);
+ getRightViewPort().getProcessors().add(0, dlsrRight);
+ getLeftViewPort().getProcessors().add(0, sceneProcessor);
}
}
// make sure each has a translucent filter renderer
diff --git a/jme3-vr/src/main/java/com/jme3/util/VRViewManager.java b/jme3-vr/src/main/java/com/jme3/util/VRViewManager.java
index e2c503006..58a6c166e 100644
--- a/jme3-vr/src/main/java/com/jme3/util/VRViewManager.java
+++ b/jme3-vr/src/main/java/com/jme3/util/VRViewManager.java
@@ -42,17 +42,25 @@ public interface VRViewManager {
/**
* Get the {@link ViewPort viewport} attached to the left eye.
* @return the {@link ViewPort viewport} attached to the left eye.
- * @see #getRightViewport()
+ * @see #getRightViewPort()
*/
- public ViewPort getLeftViewport();
+ public ViewPort getLeftViewPort();
/**
* Get the {@link ViewPort viewport} attached to the right eye.
* @return the {@link ViewPort viewport} attached to the right eye.
- * @see #getLeftViewport()
+ * @see #getLeftViewPort()
*/
- public ViewPort getRightViewport();
+ public ViewPort getRightViewPort();
+
+ /**
+ * Get the {@link ViewPort view port} attached to the mirror display.
+ * @return the view port attached to the mirror display.
+ * @see #getLeftViewPort()
+ * @see #getRightViewPort()
+ */
+ public ViewPort getMirrorViewPort();
/**
* Get the texture attached to the left eye.
diff --git a/jme3-vr/src/main/java/com/jme3/util/VRViewManagerOSVR.java b/jme3-vr/src/main/java/com/jme3/util/VRViewManagerOSVR.java
index 9b78396e5..e3d85406e 100644
--- a/jme3-vr/src/main/java/com/jme3/util/VRViewManagerOSVR.java
+++ b/jme3-vr/src/main/java/com/jme3/util/VRViewManagerOSVR.java
@@ -117,18 +117,18 @@ public class VRViewManagerOSVR extends AbstractVRViewManager{
/**
* Get the {@link ViewPort viewport} attached to the left eye.
* @return the {@link ViewPort viewport} attached to the left eye.
- * @see #getRightViewport()
+ * @see #getRightViewPort()
*/
- public ViewPort getLeftViewport() {
+ 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()
+ * @see #getLeftViewPort()
*/
- public ViewPort getRightViewport() {
+ public ViewPort getRightViewPort() {
return rightViewport;
}
diff --git a/jme3-vr/src/main/java/com/jme3/util/VRViewManagerOpenVR.java b/jme3-vr/src/main/java/com/jme3/util/VRViewManagerOpenVR.java
index 49d08578b..545754a59 100644
--- a/jme3-vr/src/main/java/com/jme3/util/VRViewManagerOpenVR.java
+++ b/jme3-vr/src/main/java/com/jme3/util/VRViewManagerOpenVR.java
@@ -7,6 +7,7 @@ package com.jme3.util;
import com.jme3.app.VREnvironment;
import com.jme3.input.vr.OpenVR;
import com.jme3.input.vr.VRAPI;
+import com.jme3.input.vr.VRTrackedController;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Quaternion;
@@ -346,10 +347,10 @@ public class VRViewManagerOpenVR extends AbstractVRViewManager {
return;
}
- leftEyeTexture = (Texture2D) getLeftViewport().getOutputFrameBuffer().getColorBuffer().getTexture();
- rightEyeTexture = (Texture2D)getRightViewport().getOutputFrameBuffer().getColorBuffer().getTexture();
- leftEyeDepth = (Texture2D) getLeftViewport().getOutputFrameBuffer().getDepthBuffer().getTexture();
- rightEyeDepth = (Texture2D)getRightViewport().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
@@ -387,6 +388,7 @@ public class VRViewManagerOpenVR extends AbstractVRViewManager {
if( environment.getApplication().getContext().getSettings().isSwapBuffers() ) {
setupMirrorBuffers(environment.getCamera(), leftEyeTexture, false);
+
}
} else {
throw new IllegalStateException("This VR environment is not attached to any application.");
@@ -414,9 +416,35 @@ public class VRViewManagerOpenVR extends AbstractVRViewManager {
// grab the hardware handle
VRAPI dev = environment.getVRHardware();
if( dev != null ) {
+
+
// update the HMD's position & orientation
dev.updatePose();
dev.getPositionAndOrientation(hmdPos, hmdRot);
+/*
+ // TOREMOVE
+ Vector3f v = dev.getVRinput().getTrackedController(0).getPosition();
+ Quaternion q = dev.getVRinput().getTrackedController(0).getOrientation();
+ if ((v != null)&&(q != null)){
+ hmdPos.set(v);
+ hmdRot.set(q);
+ }
+
+ logger.severe("HMD controller ");
+ logger.severe(" Position "+hmdPos);
+ logger.severe(" Orientation "+hmdRot);
+
+ VRTrackedController tc = null;
+ for(int i = 0; i < dev.getVRinput().getTrackedControllerCount(); i++){
+ tc = dev.getVRinput().getTrackedController(i);
+ logger.severe("Tracked controller "+i+": "+tc.getControllerName());
+ logger.severe(" Position "+tc.getPosition());
+ logger.severe(" Orientation "+tc.getOrientation());
+ logger.severe("");
+ }
+*/
+ // TOREMOVE
+
if( obs != null ) {
// update hmdPos based on obs rotation
finalRotation.set(objRot);
@@ -490,18 +518,18 @@ public class VRViewManagerOpenVR extends AbstractVRViewManager {
//org.lwjgl.opengl.GL11.glEnable(org.lwjgl.opengl.GL30.GL_FRAMEBUFFER_SRGB);
if( !environment.isInstanceRendering()) {
- leftViewport = setupViewBuffers(getLeftCamera(), LEFT_VIEW_NAME);
+ leftViewPort = setupViewBuffers(getLeftCamera(), LEFT_VIEW_NAME);
rightCamera = getLeftCamera().clone();
if( environment.getVRHardware() != null ){
getRightCamera().setProjectionMatrix(environment.getVRHardware().getHMDMatrixProjectionRightEye(getRightCamera()));
}
- rightViewport = setupViewBuffers(getRightCamera(), RIGHT_VIEW_NAME);
+ rightViewPort = setupViewBuffers(getRightCamera(), RIGHT_VIEW_NAME);
} else {
if (environment.getApplication() != null){
logger.severe("THIS CODE NEED CHANGES !!!");
- leftViewport = environment.getApplication().getViewPort();
+ leftViewPort = environment.getApplication().getViewPort();
//leftViewport.attachScene(app.getRootNode());
rightCamera = getLeftCamera().clone();
if( environment.getVRHardware() != null ){
@@ -520,7 +548,7 @@ public class VRViewManagerOpenVR extends AbstractVRViewManager {
}
// setup gui
- environment.getVRGUIManager().setupGui(getLeftCamera(), getRightCamera(), getLeftViewport(), getRightViewport());
+ environment.getVRGUIManager().setupGui(getLeftCamera(), getRightCamera(), getLeftViewPort(), getRightViewPort());
if( environment.getVRHardware() != null ) {
// call these to cache the results internally