瀏覽代碼

Merge pull request #607 from jseinturier/jme3-vr-dev

Jme3 vr dev
empirephoenix 8 年之前
父節點
當前提交
08de4e5687
共有 100 個文件被更改,包括 14958 次插入32 次删除
  1. 8 0
      .gitignore
  2. 89 32
      jme3-core/src/main/java/com/jme3/scene/Spatial.java
  3. 17 0
      jme3-vr/build.gradle
  4. 843 0
      jme3-vr/src/main/java/com/jme3/app/VRAppState.java
  5. 1534 0
      jme3-vr/src/main/java/com/jme3/app/VRApplication.java
  6. 147 0
      jme3-vr/src/main/java/com/jme3/app/VRConstants.java
  7. 140 0
      jme3-vr/src/main/java/com/jme3/input/lwjgl/GlfwKeyInputVR.java
  8. 329 0
      jme3-vr/src/main/java/com/jme3/input/lwjgl/GlfwMouseInputVR.java
  9. 64 0
      jme3-vr/src/main/java/com/jme3/input/vr/HmdType.java
  10. 470 0
      jme3-vr/src/main/java/com/jme3/input/vr/OSVR.java
  11. 365 0
      jme3-vr/src/main/java/com/jme3/input/vr/OSVRInput.java
  12. 533 0
      jme3-vr/src/main/java/com/jme3/input/vr/OpenVR.java
  13. 410 0
      jme3-vr/src/main/java/com/jme3/input/vr/OpenVRInput.java
  14. 196 0
      jme3-vr/src/main/java/com/jme3/input/vr/VRAPI.java
  15. 61 0
      jme3-vr/src/main/java/com/jme3/input/vr/VRBounds.java
  16. 205 0
      jme3-vr/src/main/java/com/jme3/input/vr/VRInputAPI.java
  17. 51 0
      jme3-vr/src/main/java/com/jme3/input/vr/VRInputType.java
  18. 10 0
      jme3-vr/src/main/java/com/jme3/input/vr/VRTrackedController.java
  19. 159 0
      jme3-vr/src/main/java/com/jme3/post/CartoonSSAO.java
  20. 210 0
      jme3-vr/src/main/java/com/jme3/post/OpenVRFilter.java
  21. 71 0
      jme3-vr/src/main/java/com/jme3/post/PreNormalCaching.java
  22. 332 0
      jme3-vr/src/main/java/com/jme3/shadow/AbstractShadowFilterVR.java
  23. 834 0
      jme3-vr/src/main/java/com/jme3/shadow/AbstractShadowRendererVR.java
  24. 167 0
      jme3-vr/src/main/java/com/jme3/shadow/DirectionalLightShadowFilterVR.java
  25. 312 0
      jme3-vr/src/main/java/com/jme3/shadow/DirectionalLightShadowRendererVR.java
  26. 48 0
      jme3-vr/src/main/java/com/jme3/shadow/InstancedDirectionalShadowFilter.java
  27. 78 0
      jme3-vr/src/main/java/com/jme3/shadow/VRDirectionalLightShadowRenderer.java
  28. 49 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/AppOverrideKeys_t.java
  29. 89 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/COpenVRContext.java
  30. 53 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/CameraVideoStreamFrameHeader_t.java
  31. 43 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/Compositor_CumulativeStats.java
  32. 53 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/Compositor_FrameTiming.java
  33. 43 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/Compositor_OverlaySettings.java
  34. 53 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/D3D12TextureData_t.java
  35. 63 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/DistortionCoordinates_t.java
  36. 43 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/HiddenAreaMesh_t.java
  37. 39 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/HmdColor_t.java
  38. 43 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/HmdMatrix34_t.java
  39. 43 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/HmdMatrix44_t.java
  40. 43 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/HmdQuad_t.java
  41. 39 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/HmdQuaternion_t.java
  42. 41 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/HmdRect2_t.java
  43. 43 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/HmdVector2_t.java
  44. 43 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/HmdVector3_t.java
  45. 43 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/HmdVector3d_t.java
  46. 43 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/HmdVector4_t.java
  47. 37 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/IntersectionMaskCircle_t.java
  48. 39 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/IntersectionMaskRectangle_t.java
  49. 1841 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/JOpenVRLibrary.java
  50. 47 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/NotificationBitmap_t.java
  51. 778 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/OpenVRUtil.java
  52. 45 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/RenderModel_ComponentState_t.java
  53. 33 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/RenderModel_ControllerMode_State_t.java
  54. 45 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/RenderModel_TextureMap_t.java
  55. 51 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/RenderModel_Vertex_t.java
  56. 58 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/RenderModel_t.java
  57. 57 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/Texture_t.java
  58. 57 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/TrackedDevicePose_t.java
  59. 35 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VRControllerAxis_t.java
  60. 49 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VRControllerState_t.java
  61. 35 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_ApplicationLaunch_t.java
  62. 35 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Chaperone_t.java
  63. 33 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Controller_t.java
  64. 135 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Data_t.java
  65. 35 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_EditingCameraSurface_t.java
  66. 33 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Ipd_t.java
  67. 45 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Keyboard_t.java
  68. 33 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_MessageOverlay_t.java
  69. 37 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Mouse_t.java
  70. 35 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Notification_t.java
  71. 33 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Overlay_t.java
  72. 33 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_PerformanceTest_t.java
  73. 37 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Process_t.java
  74. 45 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Property_t.java
  75. 35 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Reserved_t.java
  76. 33 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_ScreenshotProgress_t.java
  77. 35 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Screenshot_t.java
  78. 37 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Scroll_t.java
  79. 33 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_SeatedZeroPoseReset_t.java
  80. 33 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Status_t.java
  81. 43 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_TouchPadMove_t.java
  82. 48 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_t.java
  83. 39 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VROverlayIntersectionMaskPrimitive_Data_t.java
  84. 45 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VROverlayIntersectionMaskPrimitive_t.java
  85. 49 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VROverlayIntersectionParams_t.java
  86. 47 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VROverlayIntersectionResults_t.java
  87. 39 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VRTextureBounds_t.java
  88. 58 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VRVulkanTextureData_t.java
  89. 216 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VR_IVRApplications_FnTable.java
  90. 151 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VR_IVRChaperoneSetup_FnTable.java
  91. 99 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VR_IVRChaperone_FnTable.java
  92. 278 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VR_IVRCompositor_FnTable.java
  93. 59 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VR_IVRExtendedDisplay_FnTable.java
  94. 51 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VR_IVRNotifications_FnTable.java
  95. 483 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VR_IVROverlay_FnTable.java
  96. 139 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VR_IVRRenderModels_FnTable.java
  97. 50 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VR_IVRResources_FnTable.java
  98. 91 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VR_IVRScreenshots_FnTable.java
  99. 102 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VR_IVRSettings_FnTable.java
  100. 297 0
      jme3-vr/src/main/java/com/jme3/system/jopenvr/VR_IVRSystem_FnTable.java

+ 8 - 0
.gitignore

@@ -1,4 +1,7 @@
 **/nbproject/private/
+**/.classpath
+**/.settings
+**/.project
 /.gradle/
 /.nb-gradle/
 /.idea/
@@ -35,3 +38,8 @@
 !/jme3-bullet-native/libs/native/osx/x86_64/libbulletjme.dylib
 !/jme3-bullet-native/libs/native/linux/x86/libbulletjme.so
 !/jme3-bullet-native/libs/native/linux/x86_64/libbulletjme.so
+!/jme3-vr/src/main/resources/**/*.dylib
+!/jme3-vr/src/main/resources/**/*.so
+!/jme3-vr/src/main/resources/**/*.so.dbg
+!/jme3-vr/src/main/resources/**/*.dll
+!/jme3-vr/src/main/resources/**/*.pdb

+ 89 - 32
jme3-core/src/main/java/com/jme3/scene/Spatial.java

@@ -170,6 +170,60 @@ public abstract class Spatial implements Savable, Cloneable, Collidable, Cloneab
      */
     protected transient int refreshFlags = 0;
 
+    public void refreshFlagOr(int flag){
+    	refreshFlags |= flag;
+    	//logger.warning("Changing refresh flags for spatial " + getName()+", flags: "+getRefreshFlagsDescription());
+    }
+    
+    public void refreshFlagAnd(int flag){
+    	refreshFlags &= flag;
+    	//logger.warning("Changing refresh flags for spatial " + getName()+", flags: "+getRefreshFlagsDescription());
+    }
+    
+    public int refreshFlagGetAnd(int flag){
+    	return (refreshFlags & flag);
+    }
+    
+    public int getRefreshFlags(){
+    	return refreshFlags;
+    }
+    
+    public String getRefreshFlagsDescription(){
+    	String str = "";
+    	
+    	if (refreshFlags == 0){
+    		str += "OK";
+    	} else {
+    		
+    		// need light resort + combine transforms
+    		if ((refreshFlags & RF_TRANSFORM) == RF_TRANSFORM){
+    		  str += "RF_TRANSFORM ";
+    		}
+    		
+    		// need light resort + combine transforms
+    		if ((refreshFlags & RF_BOUND) == RF_BOUND){
+    		  str += "RF_BOUND ";
+    		}
+
+    		// changes in light lists 
+    		if ((refreshFlags & RF_LIGHTLIST) == RF_LIGHTLIST){
+    		  str += "RF_LIGHTLIST ";
+    		}
+    		
+    		// some child need geometry update
+    		if ((refreshFlags & RF_CHILD_LIGHTLIST) == RF_CHILD_LIGHTLIST){
+    		  str += "RF_CHILD_LIGHTLIST ";
+    		}
+    		
+    		// some child need geometry update
+    		if ((refreshFlags & RF_MATPARAM_OVERRIDE) == RF_MATPARAM_OVERRIDE){
+    		  str += "RF_MATPARAM_OVERRIDE ";
+    		}
+    	}
+    	
+    	return str;
+    }
+    
     /**
      * Set to true if a subclass requires updateLogicalState() even
      * if it doesn't have any controls.  Defaults to true thus implementing
@@ -209,7 +263,7 @@ public abstract class Spatial implements Savable, Cloneable, Collidable, Cloneab
 
         localOverrides = new SafeArrayList<>(MatParamOverride.class);
         worldOverrides = new SafeArrayList<>(MatParamOverride.class);
-        refreshFlags |= RF_BOUND;
+        refreshFlagOr(RF_BOUND);
     }
 
     public void setKey(AssetKey key) {
@@ -272,35 +326,35 @@ public abstract class Spatial implements Savable, Cloneable, Collidable, Cloneab
      * a refresh is required.
      */
     protected void setTransformRefresh() {
-        refreshFlags |= RF_TRANSFORM;
+    	refreshFlagOr(RF_TRANSFORM);
         setBoundRefresh();
     }
 
     protected void setLightListRefresh() {
-        refreshFlags |= RF_LIGHTLIST;
+    	refreshFlagOr(RF_LIGHTLIST);
         // Make sure next updateGeometricState() visits this branch
         // to update lights.
         Spatial p = parent;
         while (p != null) {
-            if ((p.refreshFlags & RF_CHILD_LIGHTLIST) != 0) {
+            if ((p.refreshFlagGetAnd(RF_CHILD_LIGHTLIST)) != 0) {
                 // The parent already has this flag,
                 // so must all ancestors.
                 return;
             }
-            p.refreshFlags |= RF_CHILD_LIGHTLIST;
+            p.refreshFlagOr(RF_CHILD_LIGHTLIST);
             p = p.parent;
         }
     }
 
     protected void setMatParamOverrideRefresh() {
-        refreshFlags |= RF_MATPARAM_OVERRIDE;
+    	refreshFlagOr(RF_MATPARAM_OVERRIDE);
         Spatial p = parent;
         while (p != null) {
-            if ((p.refreshFlags & RF_MATPARAM_OVERRIDE) != 0) {
+            if ((p.refreshFlagGetAnd(RF_MATPARAM_OVERRIDE)) != 0) {
                 return;
             }
 
-            p.refreshFlags |= RF_MATPARAM_OVERRIDE;
+            p.refreshFlagOr(RF_MATPARAM_OVERRIDE);
             p = p.parent;
         }
     }
@@ -310,15 +364,15 @@ public abstract class Spatial implements Savable, Cloneable, Collidable, Cloneab
      * a refresh is required.
      */
     protected void setBoundRefresh() {
-        refreshFlags |= RF_BOUND;
+    	refreshFlagOr(RF_BOUND);
 
         Spatial p = parent;
         while (p != null) {
-            if ((p.refreshFlags & RF_BOUND) != 0) {
+            if ((p.refreshFlagGetAnd(RF_BOUND)) != 0) {
                 return;
             }
 
-            p.refreshFlags |= RF_BOUND;
+            p.refreshFlagOr(RF_BOUND);
             p = p.parent;
         }
     }
@@ -353,11 +407,14 @@ public abstract class Spatial implements Savable, Cloneable, Collidable, Cloneab
      * (should be rendered), false if outside.
      */
     public boolean checkCulling(Camera cam) {
-        if (refreshFlags != 0) {
+        if (getRefreshFlags() != 0) {
+        	/*
             throw new IllegalStateException("Scene graph is not properly updated for rendering.\n"
                     + "State was changed after rootNode.updateGeometricState() call. \n"
                     + "Make sure you do not modify the scene from another thread!\n"
-                    + "Problem spatial name: " + getName());
+                    + "Problem spatial name: " + getName()+", flags: "+getRefreshFlagsDescription());
+                    */
+        	logger.warning("Invalid refresh flags for spatial " + getName()+", flags: "+getRefreshFlagsDescription());
         }
 
         CullHint cm = getCullHint();
@@ -571,28 +628,28 @@ public abstract class Spatial implements Savable, Cloneable, Collidable, Cloneab
         // for a node, the world bound is a combination of all it's children
         // bounds
         // -> handled by subclass
-        refreshFlags &= ~RF_BOUND;
+    	refreshFlagAnd(~RF_BOUND);
     }
 
     protected void updateWorldLightList() {
         if (parent == null) {
             worldLights.update(localLights, null);
-            refreshFlags &= ~RF_LIGHTLIST;
+            refreshFlagAnd(~RF_LIGHTLIST);
         } else {
-            assert (parent.refreshFlags & RF_LIGHTLIST) == 0;
+            assert (parent.refreshFlagGetAnd(RF_LIGHTLIST)) == 0;
             worldLights.update(localLights, parent.worldLights);
-            refreshFlags &= ~RF_LIGHTLIST;
+            refreshFlagAnd(~RF_LIGHTLIST);
         }
     }
 
     protected void updateMatParamOverrides() {
-        refreshFlags &= ~RF_MATPARAM_OVERRIDE;
+    	refreshFlagAnd(~RF_MATPARAM_OVERRIDE);
 
         worldOverrides.clear();
         if (parent == null) {
             worldOverrides.addAll(localOverrides);
         } else {
-            assert (parent.refreshFlags & RF_MATPARAM_OVERRIDE) == 0;
+            assert (parent.refreshFlagGetAnd(RF_MATPARAM_OVERRIDE)) == 0;
             worldOverrides.addAll(parent.worldOverrides);
             worldOverrides.addAll(localOverrides);
         }
@@ -643,13 +700,13 @@ public abstract class Spatial implements Savable, Cloneable, Collidable, Cloneab
     protected void updateWorldTransforms() {
         if (parent == null) {
             worldTransform.set(localTransform);
-            refreshFlags &= ~RF_TRANSFORM;
+            refreshFlagAnd(~RF_TRANSFORM);
         } else {
             // check if transform for parent is updated
-            assert ((parent.refreshFlags & RF_TRANSFORM) == 0);
+            assert ((parent.refreshFlagGetAnd(RF_TRANSFORM)) == 0);
             worldTransform.set(localTransform);
             worldTransform.combineWithParent(parent.worldTransform);
-            refreshFlags &= ~RF_TRANSFORM;
+            refreshFlagAnd(~RF_TRANSFORM);
         }
     }
 
@@ -658,13 +715,13 @@ public abstract class Spatial implements Savable, Cloneable, Collidable, Cloneab
      * efficient manner possible.
      */
     void checkDoTransformUpdate() {
-        if ((refreshFlags & RF_TRANSFORM) == 0) {
+        if ((refreshFlagGetAnd(RF_TRANSFORM)) == 0) {
             return;
         }
 
         if (parent == null) {
             worldTransform.set(localTransform);
-            refreshFlags &= ~RF_TRANSFORM;
+            refreshFlagAnd(~RF_TRANSFORM);
         } else {
             TempVars vars = TempVars.get();
 
@@ -675,14 +732,14 @@ public abstract class Spatial implements Savable, Cloneable, Collidable, Cloneab
                 Spatial hisParent = rootNode.parent;
                 if (hisParent == null) {
                     rootNode.worldTransform.set(rootNode.localTransform);
-                    rootNode.refreshFlags &= ~RF_TRANSFORM;
+                    rootNode.refreshFlagAnd(~RF_TRANSFORM);
                     i--;
                     break;
                 }
 
                 stack[i] = rootNode;
 
-                if ((hisParent.refreshFlags & RF_TRANSFORM) == 0) {
+                if ((hisParent.refreshFlagGetAnd(RF_TRANSFORM)) == 0) {
                     break;
                 }
 
@@ -707,7 +764,7 @@ public abstract class Spatial implements Savable, Cloneable, Collidable, Cloneab
      * manner possible.
      */
     void checkDoBoundUpdate() {
-        if ((refreshFlags & RF_BOUND) == 0) {
+        if ((refreshFlagGetAnd(RF_BOUND)) == 0) {
             return;
         }
 
@@ -897,20 +954,20 @@ public abstract class Spatial implements Savable, Cloneable, Collidable, Cloneab
 
         // NOTE: Update world transforms first because
         // bound transform depends on them.
-        if ((refreshFlags & RF_LIGHTLIST) != 0) {
+        if ((refreshFlagGetAnd(RF_LIGHTLIST)) != 0) {
             updateWorldLightList();
         }
-        if ((refreshFlags & RF_TRANSFORM) != 0) {
+        if ((refreshFlagGetAnd(RF_TRANSFORM)) != 0) {
             updateWorldTransforms();
         }
-        if ((refreshFlags & RF_BOUND) != 0) {
+        if ((refreshFlagGetAnd(RF_BOUND)) != 0) {
             updateWorldBound();
         }
-        if ((refreshFlags & RF_MATPARAM_OVERRIDE) != 0) {
+        if ((refreshFlagGetAnd(RF_MATPARAM_OVERRIDE)) != 0) {
             updateMatParamOverrides();
         }
         
-        assert refreshFlags == 0;
+        assert getRefreshFlags() == 0;
     }
 
     /**

+ 17 - 0
jme3-vr/build.gradle

@@ -0,0 +1,17 @@
+if (!hasProperty('mainClass')) {
+    ext.mainClass = ''
+}
+
+def lwjglVersion = '3.0.0'
+
+sourceCompatibility = '1.8'
+
+dependencies {
+    compile project(':jme3-core')
+    compile project(':jme3-lwjgl3')
+    compile project(':jme3-effects')
+	
+	// https://mvnrepository.com/artifact/net.java.dev.jna/jna
+    compile group: 'net.java.dev.jna', name: 'jna', version: '4.3.0'
+    compile 'com.nativelibs4java:jnaerator-runtime:0.12'
+}

+ 843 - 0
jme3-vr/src/main/java/com/jme3/app/VRAppState.java

@@ -0,0 +1,843 @@
+package com.jme3.app;
+
+
+import com.jme3.app.Application;
+import com.jme3.app.state.AbstractAppState;
+import com.jme3.app.state.AppStateManager;
+import com.jme3.input.vr.OSVR;
+import com.jme3.input.vr.OpenVR;
+import com.jme3.input.vr.VRAPI;
+import com.jme3.input.vr.VRInputAPI;
+import com.jme3.math.ColorRGBA;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Vector3f;
+import com.jme3.post.PreNormalCaching;
+import com.jme3.renderer.Camera;
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.ViewPort;
+import com.jme3.scene.Spatial;
+import com.jme3.system.AppSettings;
+import com.jme3.system.jopenvr.JOpenVRLibrary;
+
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import jmevr.util.VRGuiManager;
+import jmevr.util.VRMouseManager;
+import jmevr.util.VRViewManager;
+import jmevr.util.VRGuiManager.POSITIONING_MODE;
+
+/**
+ * A JMonkey app state dedicated to Virtual Reality. 
+ * An application that want to use VR devices (HTC vive, ...) has to use this app state.<br>
+ * As this app state and the main {@link Application application} have to share {@link AppSettings application settings}, 
+ * the common way to use this app state is:<br>
+ * <ul>
+ * <li>To create {@link AppSettings application settings} and set the VR related settings (see {@link VRConstants}).
+ * <li>To instantiate this app state with the created settings.
+ * <li>To instantiate the main {@link Application application} and to attach it to the created settings (with {@link Application#setSettings(AppSettings) setSettings(AppSettings)}).
+ * <li>To start the main {@link Application application}.
+ * </ul>
+ * Attaching an instance of this app state to an already started application may cause crashes.
+ * @author Julien Seinturier - JOrigin project - <a href="http://www.jorigin.org">http:/www.jorigin.org</a>
+ */
+public class VRAppState extends AbstractAppState {
+
+    private static final Logger logger = Logger.getLogger(VRAppState.class.getName());
+    
+    /**
+     * The underlying system VR API. By default set to {@link VRConstants#SETTING_VRAPI_OPENVR_VALUE}.
+     */
+    public int vrBinding = VRConstants.SETTING_VRAPI_OPENVR_VALUE;
+    
+    /**
+     * Is the application has not to start within VR mode (default is <code>false</code>).
+     */
+    public boolean DISABLE_VR = false;
+    
+    private VRAPI VRhardware            = null;
+    private VRGuiManager guiManager     = null;
+    private VRMouseManager mouseManager = null;
+    private VRViewManager viewmanager   = null;
+    
+    private String OS;
+    
+    private Camera dummyCam;
+    
+    private Spatial observer = null;
+    
+    private boolean VRSupportedOS;
+    private boolean forceVR            = false;;
+    private boolean disableSwapBuffers = true;
+    private boolean disableVR          = false;
+    private boolean seated;
+    private boolean nogui;
+    private boolean instanceVR         = false;
+
+	private float defaultFOV           = 108f;
+    private float defaultAspect        = 1f;
+    
+   
+    
+    private float fFar  = 1000f;
+    private float fNear = 0.1f;
+    private int xWin    = 1920;
+    private int yWin    = 1080;
+    
+    private float resMult = 1f;
+    
+    private boolean useCompositor = true;
+    private boolean compositorOS;
+    
+    /*
+     where is the headset pointing, after all rotations are combined?
+     depends on observer rotation, if any
+     */
+    private Quaternion tempq = new Quaternion();
+    
+    private Application application      = null;
+    private AppStateManager stateManager = null;
+    private AppSettings settings         = null;
+    
+    
+    /**
+     * Create a new default VR app state.
+     */
+    public VRAppState() {
+        super();
+
+        dummyCam = new Camera();
+        
+        // Create the GUI manager.
+        guiManager = new VRGuiManager();
+        
+        // Create a new view manager.
+        viewmanager = new VRViewManager();
+
+        // Create a new mouse manager.
+        mouseManager = new VRMouseManager();
+      
+     }
+    
+    /**
+     * Create a new VR app state with given settings. 
+     * @param settings the settings to use.
+     */
+    public VRAppState(AppSettings settings){
+      this();
+      this.settings = settings;
+      processSettings(settings);
+    }
+
+    
+    /**
+     * Simple update of the app state, this method should contains any spatial updates.
+     * This method is called by the {@link #update(float) update()} method and should not be called manually.
+     * @param tpf the application time.
+     */
+    public void simpleUpdate(float tpf) {
+    	return;
+    }
+    
+    /**
+     * Rendering callback of the app state. This method is called by the {@link #update(float) update()} method and should not be called manually.
+     * @param renderManager the {@link RenderManager render manager}.
+     */
+    public void simpleRender(RenderManager renderManager) {
+        PreNormalCaching.resetCache(isInVR());
+    }
+
+    /**
+     * Set the frustrum values for the application.
+     * @param near the frustrum near value.
+     * @param far the frustrum far value.
+     */
+    public void setFrustrumNearFar(float near, float far) {
+        fNear = near;
+        fFar = far;
+    }
+    
+    /**
+     * Set the mirror window size in pixel.
+     * @param width the width of the mirror window in pixel.
+     * @param height the height of the mirror window in pixel.
+     */
+    public void setMirrorWindowSize(int width, int height) {
+        xWin = width;
+        yWin = height;
+    }
+    
+    /**
+     * Set the resolution multiplier.
+     * @param val the resolution multiplier.
+     */
+    public void setResolutionMultiplier(float val) {
+        resMult = val;
+        if( viewmanager != null ){
+        	viewmanager.setResolutionMultiplier(resMult);
+        }
+    }
+
+    /**
+     * Is the VR compositor is active.
+     * @return <code>true</code> if the VR compositor is active and <code>false</code> otherwise.
+     */
+    public boolean compositorAllowed() {
+        return useCompositor && compositorOS;
+    }
+    
+    /**
+     * Get if the system currently support VR.
+     * @return <code>true</code> if the system currently support VR and <code>false</Code> otherwise.
+     */
+    public boolean isVRSupported() {
+        return VRSupportedOS;
+    }
+    
+    /**
+     * Get the {@link Camera camera} attached to this application state. 
+     * If the VR mode is {@link #isInVR() active}, this method return a dummy camera, otherwise, 
+     * this method return the camera of the attached application.
+     * @return the camera attached to this application state.
+     */
+    public Camera getCamera() {
+        if( isInVR() && viewmanager != null && viewmanager.getLeftCamera() != null ) {
+            return dummyCam;
+        }
+        
+        return application.getCamera();
+    }
+
+    /**
+     * Can be used to change seated experience during runtime.
+     * @param isSeated <code>true</code> if designed for sitting, <code>false</code> for standing/roomscale
+     * @see #isSeatedExperience()
+     */
+    public void setSeatedExperience(boolean isSeated) {
+        seated = isSeated;
+        if( VRhardware instanceof OpenVR ) {
+            if( VRhardware.getCompositor() == null ) return;
+            if( seated ) {
+                ((OpenVR)VRhardware).getCompositor().SetTrackingSpace.apply(JOpenVRLibrary.ETrackingUniverseOrigin.ETrackingUniverseOrigin_TrackingUniverseSeated);
+            } else {
+                ((OpenVR)VRhardware).getCompositor().SetTrackingSpace.apply(JOpenVRLibrary.ETrackingUniverseOrigin.ETrackingUniverseOrigin_TrackingUniverseStanding);                
+            }        
+        }
+    }
+    
+    /**
+     * Check if the application is configured as a seated experience.
+     * @return <code>true</code> if the application is configured as a seated experience and <code>false</code> otherwise.
+     * @see #setSeatedExperience(boolean)
+     */
+    public boolean isSeatedExperience() {
+        return seated;
+    }
+    
+    /**
+     * Reset headset pose if seating experience.
+     */
+    public void resetSeatedPose(){
+        if( VRSupportedOS == false || isSeatedExperience() == false ) return;
+        VRhardware.reset();
+    }
+    
+    /**
+     * Check if the rendering is instanced (see <a href="https://en.wikipedia.org/wiki/Geometry_instancing">Geometry instancing</a>).
+     * @return <code>true</code> if the rendering is instanced and <code>false</code> otherwise.
+     */
+    public boolean isInstanceVRRendering() {
+        return instanceVR && isInVR();
+    }
+    
+    /**
+     * Check if the VR mode is enabled.
+     * @return <code>true</code> if the VR mode is enabled and <code>false</code> otherwise.
+     */
+    public boolean isInVR() {
+        return DISABLE_VR == false && (forceVR || VRSupportedOS && VRhardware != null && VRhardware.isInitialized());
+    }
+    
+    /**
+     * Get the default Field Of View (FOV) value.
+     * @return the default Field Of View (FOV) value.
+     * @see #setDefaultFOV(float)
+     */
+    public float getDefaultFOV() {
+		return defaultFOV;
+	}
+
+    /**
+     * Set the default Field Of View (FOV) value.
+     * @param defaultFOV the default Field Of View (FOV) value.
+     * @see #getDefaultFOV()
+     */
+	public void setDefaultFOV(float defaultFOV) {
+		this.defaultFOV = defaultFOV;
+	}
+
+	/**
+	 * Get the default aspect ratio.
+	 * @return the default aspect ratio.
+	 * @see #setDefaultAspect(float)
+	 */
+	public float getDefaultAspect() {
+		return defaultAspect;
+	}
+
+	/**
+	 * Set the default aspect ratio.
+	 * @param defaultAspect the default aspect ratio.
+	 * @see #getDefaultAspect()
+	 */
+	public void setDefaultAspect(float defaultAspect) {
+		this.defaultAspect = defaultAspect;
+	}
+	
+    /**
+     * Move filters from the main scene into the eye's.
+     * This removes filters from the main scene.
+     */
+    public void moveScreenProcessingToVR() {
+        if( isInVR() ) {
+        	viewmanager.moveScreenProcessingToEyes();
+        }
+    }
+ 
+    /**
+     * Check if the application has a GUI overlay attached.
+     * @return <code>true</code> if the application has a GUI overlay attached and <code>false</code> otherwise.
+     */
+    public boolean hasTraditionalGUIOverlay() {
+        return !nogui;
+    }
+    
+    /**
+     * Get the scene observer. If no observer has been set, this method return the application {@link #getCamera() camera}.
+     * @return the scene observer. 
+     * @see #setObserver(Spatial)
+     */
+    public Object getObserver() {
+        if( observer == null ) {
+            return getCamera();
+        }
+        return observer;
+    }
+    
+    /**
+     * Set the scene observer. The VR headset will be linked to it. If no observer is set, the VR headset is linked to the the application {@link #getCamera() camera}.
+     * @param observer the scene observer.
+     */
+    public void setObserver(Spatial observer) {
+       this.observer = observer;
+    }
+    
+    /**
+     * Get the observer final rotation within the scene.
+     * @return the observer final rotation within the scene.
+     * @see #getFinalObserverPosition()
+     */
+    public Quaternion getFinalObserverRotation() {
+        if( viewmanager == null ) {
+            if( observer == null ) {
+                return getCamera().getRotation();
+            } else return observer.getWorldRotation();
+        }        
+        if( observer == null ) {
+            tempq.set(dummyCam.getRotation());
+        } else {
+            tempq.set(observer.getWorldRotation());
+        }
+        return tempq.multLocal(VRhardware.getOrientation());
+    }
+    
+    /**
+     * Get the observer final position within the scene.
+     * @return the observer position.
+     * @see #getFinalObserverRotation()
+     */
+    public Vector3f getFinalObserverPosition() {
+        if( viewmanager == null ) {
+            if( observer == null ) {
+                return getCamera().getLocation();
+            } else return observer.getWorldTranslation();            
+        }
+        Vector3f pos = VRhardware.getPosition();
+        if( observer == null ) {
+            dummyCam.getRotation().mult(pos, pos);
+            return pos.addLocal(dummyCam.getLocation());
+        } else {
+            observer.getWorldRotation().mult(pos, pos);
+            return pos.addLocal(observer.getWorldTranslation());
+        }
+    }
+    
+    /**
+     * Set the VR headset height from the ground.
+     * @param amount the VR headset height from the ground.
+     * @see #getVRHeightAdjustment()
+     */
+    public void setVRHeightAdjustment(float amount) {
+        if( viewmanager != null ) viewmanager.setHeightAdjustment(amount);
+    }
+    
+    /**
+     * Get the VR headset height from the ground.
+     * @return the VR headset height from the ground.
+     * @see #setVRHeightAdjustment(float)
+     */
+    public float getVRHeightAdjustment() {
+        if( viewmanager != null ){
+        	return viewmanager.getHeightAdjustment();
+        }
+        return 0f;
+    }
+    
+    /**
+     * Get the VR headset left viewport.
+     * @return the VR headset left viewport.
+     * @see #getRightViewPort()
+     */
+    public ViewPort getLeftViewPort() {
+        if( viewmanager == null ) return application.getViewPort();
+        return viewmanager.getLeftViewport();
+    }
+    
+    /**
+     * Get the VR headset right viewport.
+     * @return the VR headset right viewport.
+     * @see #getLeftViewPort()
+     */
+    public ViewPort getRightViewPort() {
+        if( viewmanager == null ) return application.getViewPort();
+        return viewmanager.getRightViewport();
+    }
+    
+    /**
+     * Set the background color for both left and right view ports.
+     * @param clr the background color.
+     */
+    public void setBackgroundColors(ColorRGBA clr) {
+        if( viewmanager == null ) {
+            application.getViewPort().setBackgroundColor(clr);
+        } else if( viewmanager.getLeftViewport() != null ) {
+        	viewmanager.getLeftViewport().setBackgroundColor(clr);
+            if( viewmanager.getRightViewport() != null ) viewmanager.getRightViewport().setBackgroundColor(clr);
+        }
+    }
+    
+    /**
+     * Get the {@link Application} to which this app state is attached.
+     * @return the {@link Application} to which this app state is attached.
+     * @see #getStateManager()
+     */
+    public Application getApplication(){
+    	return application;
+    }
+    
+    /**
+     * Get the {@link AppStateManager state manager} to which this app state is attached.
+     * @return the {@link AppStateManager state manager} to which this app state is attached.
+     * @see #getApplication()
+     */
+    public AppStateManager getStateManager(){
+    	return stateManager;
+    }
+    
+	/**
+	 * Get the VR underlying hardware.
+	 * @return the VR underlying hardware.
+	 */
+	public VRAPI getVRHardware() {
+	    return VRhardware;
+	}
+	
+	/**
+	 * Get the VR dedicated input.
+	 * @return the VR dedicated input.
+	 */
+	public VRInputAPI getVRinput() {
+	    if( VRhardware == null ){
+	    	return null;
+	    }
+	    
+	    return VRhardware.getVRinput();
+	}
+	
+	/**
+	 * Get the VR view manager.
+	 * @return the VR view manager.
+	 */
+	public VRViewManager getVRViewManager() {
+	    return viewmanager;
+	}
+	
+	/**
+	 * Get the GUI manager attached to this application.
+	 * @return the GUI manager attached to this application.
+	 */
+	public VRGuiManager getVRGUIManager(){
+		return guiManager;
+	}
+	
+	/**
+	 * Get the VR mouse manager attached to this application.
+	 * @return the VR mouse manager attached to this application.
+	 */
+	public VRMouseManager getVRMouseManager(){
+		return mouseManager;
+	}
+    
+	/**
+	 * Get the {@link AppSettings settings} attached to this app state.
+	 * @return the {@link AppSettings settings} attached to this app state.
+	 * @see #setSettings(AppSettings)
+	 */
+	public AppSettings getSettings(){
+		return settings;
+	}
+	
+	/**
+	 * Set the {@link AppSettings settings} attached to this app state.
+	 * @param settings the {@link AppSettings settings} attached to this app state.
+	 * @see #getSettings()
+	 */
+	public void setSettings(AppSettings settings){
+		this.settings = settings;
+		processSettings(settings);
+	}
+	
+    @Override
+    public void update(float tpf) {    
+        
+        // update VR pose & cameras
+        if( viewmanager != null ) {
+        	viewmanager.update(tpf);    
+        } else if( observer != null ) {
+            getCamera().setFrame(observer.getWorldTranslation(), observer.getWorldRotation());
+        }
+        
+        //FIXME: check if this code is necessary.
+        // Updates scene and gui states.
+        Iterator<Spatial> spatialIter = application.getViewPort().getScenes().iterator();
+        Spatial spatial = null;
+        while(spatialIter.hasNext()){
+        	spatial = spatialIter.next();
+        	spatial.updateLogicalState(tpf);
+        	spatial.updateGeometricState();
+        }        
+        
+        if( isInVR() == false || guiManager.getPositioningMode() == POSITIONING_MODE.MANUAL ) {
+            // only update geometric state here if GUI is in manual mode, or not in VR
+            // it will get updated automatically in the viewmanager update otherwise
+        	spatialIter = application.getGuiViewPort().getScenes().iterator();
+            spatial = null;
+            while(spatialIter.hasNext()){
+            	spatial = spatialIter.next();
+            	spatial.updateGeometricState();
+            }    
+        }
+        
+        
+        // use the analog control on the first tracked controller to push around the mouse
+        getVRMouseManager().updateAnalogAsMouse(0, null, null, null, tpf);
+    }
+
+    @Override
+    public void postRender() {
+        super.postRender();
+        // update compositor?
+        if( viewmanager != null ) {
+        	viewmanager.sendTextures();
+        }
+    }
+
+    @Override
+    public void initialize(AppStateManager stateManager, Application app) {
+        super.initialize(stateManager, app);
+        
+        this.application  = app;
+        this.stateManager = stateManager;
+        
+        // disable annoying warnings about GUI stuff being updated, which is normal behavior
+        // for late GUI placement for VR purposes
+        Logger.getLogger("com.jme3").setLevel(Level.SEVERE);     
+        
+        // VR module attch
+        guiManager.attach(this, app);
+        viewmanager.attach(this, app);
+        mouseManager.attach(this,  app);
+        
+        app.getCamera().setFrustumFar(fFar);
+        app.getCamera().setFrustumNear(fNear);
+        dummyCam = app.getCamera().clone();
+        
+        if( isInVR() ) {
+        	
+        	logger.config("VR mode enabled.");
+        	
+            if( VRhardware != null ) {
+                VRhardware.initVRCompositor(compositorAllowed());
+            } else {
+            	logger.warning("No VR system found.");
+            }
+            
+            
+            viewmanager.setResolutionMultiplier(resMult);
+            //inputManager.addMapping(RESET_HMD, new KeyTrigger(KeyInput.KEY_F9));
+            //setLostFocusBehavior(LostFocusBehavior.Disabled);
+        } else {
+        	logger.config("VR mode disabled.");
+            //viewPort.attachScene(rootNode);
+            //guiViewPort.attachScene(guiNode);
+        }
+        
+        if( viewmanager != null ) {
+        	viewmanager.initialize();
+        }
+    }
+    
+    @Override
+    public void stateAttached(AppStateManager stateManager) {
+        super.stateAttached(stateManager); //To change body of generated methods, choose Tools | Templates.
+        
+        if (settings == null) {
+            settings = new AppSettings(true);
+            logger.config("Using default settings.");
+        } else {
+        	logger.config("Using given settings.");
+        }
+        
+        // we are going to use OpenVR now, not the Oculus Rift
+        // OpenVR does support the Rift
+        OS            = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH);
+        VRSupportedOS = !OS.contains("nux") && System.getProperty("sun.arch.data.model").equalsIgnoreCase("64"); //for the moment, linux/unix causes crashes, 64-bit only
+        compositorOS  = OS.contains("indows");
+        
+        if( VRSupportedOS && disableVR == false ) {
+        	if( vrBinding == VRConstants.SETTING_VRAPI_OSVR_VALUE ) {
+                VRhardware = new OSVR(this);
+                logger.config("Creating OSVR wrapper [SUCCESS]");
+            } else if( vrBinding == VRConstants.SETTING_VRAPI_OPENVR_VALUE ) {
+                VRhardware = new OpenVR(this);
+                logger.config("Creating OpenVR wrapper [SUCCESS]");
+            } else {
+            	logger.config("Cannot create VR binding: "+vrBinding+" [FAILED]");
+            }
+        	
+            if( VRhardware.initialize() ) {
+            	logger.config("VR native wrapper initialized [SUCCESS]");
+            } else {
+            	logger.warning("VR native wrapper initialized [FAILED]");
+            }
+            }
+        
+        GraphicsDevice defDev = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
+                                    
+        if( isInVR() && !compositorAllowed() ) {
+            // "easy extended" mode
+            // setup experimental JFrame on external device
+            // first, find the VR device
+            GraphicsDevice VRdev = null;
+            GraphicsDevice[] devs = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
+            // pick the display that isn't the default one
+            for(GraphicsDevice gd : devs) {
+                if( gd != defDev ) {
+                    VRdev = gd;
+                    break;
+                }
+            }
+
+            // did we get the VR device?
+            if( VRdev != null ) {
+                // set properties for VR acceleration
+                try {   
+                    java.awt.DisplayMode useDM = null;
+                    int max = 0;
+                    for(java.awt.DisplayMode dm : VRdev.getDisplayModes()) {
+                        int check = dm.getHeight() + dm.getWidth() + dm.getRefreshRate() + dm.getBitDepth();
+                        if( check > max ) {
+                            max = check;
+                            useDM = dm;
+                        }
+                    }
+                    
+                    // create a window for the VR device
+                    settings.setWidth(useDM.getWidth());
+                    settings.setHeight(useDM.getHeight());
+                    settings.setBitsPerPixel(useDM.getBitDepth());
+                    settings.setFrequency(useDM.getRefreshRate());
+                    settings.setSwapBuffers(true);
+                    settings.setVSync(true); // allow vsync on this display
+                    stateManager.getApplication().setSettings(settings);
+                    logger.config("Updated underlying application settings.");
+                    
+                    //VRdev.setFullScreenWindow(VRwindow);
+                    // make sure we are in the right display mode
+                    if( VRdev.getDisplayMode().equals(useDM) == false ) {
+                        VRdev.setDisplayMode(useDM);
+                    }
+                    
+                    return;
+                } catch(Exception e) { 
+                    logger.log(Level.SEVERE, e.getMessage(), e);
+                }
+            } else {
+            	logger.config("Cannot access to external screen.");
+            }
+        } else {
+        	if (!isInVR()){
+        	  logger.config("Cannot switch to VR mode (VR disabled by user).");
+        	} else if (!compositorAllowed()){
+        	  logger.warning("Cannot switch to VR mode (VR not supported).");
+        	}
+        }
+        
+        if( !isInVR() ) {
+        	
+        	//FIXME: Handling GLFW workaround on MacOS
+        	boolean macOs = false;
+            if (macOs) {
+                // GLFW workaround on macs
+                settings.setFrequency(defDev.getDisplayMode().getRefreshRate());
+                settings.setDepthBits(24);
+                settings.setVSync(true);
+                // try and read resolution from file in local dir
+                File resfile = new File("resolution.txt");
+                if( resfile.exists() ) {
+                    try {
+                        BufferedReader br = new BufferedReader(new FileReader(resfile));
+                        settings.setWidth(Integer.parseInt(br.readLine()));
+                        settings.setHeight(Integer.parseInt(br.readLine()));
+                        try {
+                            settings.setFullscreen(br.readLine().toLowerCase(Locale.ENGLISH).contains("full"));
+                        } catch(Exception e) {
+                            settings.setFullscreen(false);
+                        }
+                        br.close();
+                    } catch(Exception e) {
+                        settings.setWidth(1280);
+                        settings.setHeight(720);
+                    }
+                } else {
+                    settings.setWidth(1280);
+                    settings.setHeight(720);
+                    settings.setFullscreen(false);
+                }
+                settings.setResizable(false);
+            }
+            settings.setSwapBuffers(true);
+        } else {
+            // use basic mirroring window, skip settings window
+            settings.setSamples(1);
+            settings.setWidth(xWin);
+            settings.setHeight(yWin);
+            settings.setBitsPerPixel(32);     
+            settings.setFrameRate(0);
+            settings.setFrequency(VRhardware.getDisplayFrequency());
+            settings.setFullscreen(false);
+            settings.setVSync(false); // stop vsyncing on primary monitor!
+            settings.setSwapBuffers(disableSwapBuffers);
+        }
+
+        // Updating application settings
+        stateManager.getApplication().setSettings(settings);
+        logger.config("Updated underlying application settings.");
+        
+    }
+
+    @Override
+    public void cleanup() {
+        if( VRhardware != null ) {
+            VRhardware.destroy();
+            VRhardware = null;
+        }        
+        disableVR = true;
+        
+        this.application  = null;
+        this.stateManager = null;
+    }
+    
+    @Override
+    public void stateDetached(AppStateManager stateManager) {
+      super.stateDetached(stateManager);
+    }
+    
+    /**
+     * Process the attached settings and apply changes to this app state.
+     * @param settings the app settings to process.
+     */
+    protected void processSettings(AppSettings settings){
+    	if (settings != null){
+    		if (settings.get(VRConstants.SETTING_USE_COMPOSITOR) != null){
+    			useCompositor = settings.getBoolean(VRConstants.SETTING_USE_COMPOSITOR);
+                if( useCompositor == false ){
+                	disableSwapBuffers = false;
+                }
+    		}
+
+            if (settings.get(VRConstants.SETTING_VR_FORCE) != null){
+            	forceVR = settings.getBoolean(VRConstants.SETTING_VR_FORCE);
+    		}
+    		
+            if (settings.get(VRConstants.SETTING_FLIP_EYES) != null){
+                if( VRhardware != null ){
+                	VRhardware._setFlipEyes(settings.getBoolean(VRConstants.SETTING_FLIP_EYES));
+                } 
+    		}
+    	    
+            if (settings.get(VRConstants.SETTING_GUI_OVERDRAW) != null){
+            	guiManager._enableGuiOverdraw(settings.getBoolean(VRConstants.SETTING_GUI_OVERDRAW));
+    		}
+    	    
+            if (settings.get(VRConstants.SETTING_GUI_CURVED_SURFACE) != null){
+            	guiManager._enableCurvedSuface(settings.getBoolean(VRConstants.SETTING_GUI_CURVED_SURFACE));
+    		}
+    	    
+            if (settings.get(VRConstants.SETTING_ENABLE_MIRROR_WINDOW) != null){
+                if( useCompositor == false ) {
+                    disableSwapBuffers = false;
+                } else {
+                	disableSwapBuffers = !settings.getBoolean(VRConstants.SETTING_ENABLE_MIRROR_WINDOW);
+                }
+    		}
+    	    
+            if (settings.get(VRConstants.SETTING_DISABLE_VR) != null){
+                DISABLE_VR = settings.getBoolean(VRConstants.SETTING_DISABLE_VR);
+    		}
+    	    
+            if (settings.get(VRConstants.SETTING_SEATED_EXPERIENCE) != null){
+            	seated = settings.getBoolean(VRConstants.SETTING_SEATED_EXPERIENCE);
+    		}
+    	    
+            if (settings.get(VRConstants.SETTING_NO_GUI) != null){
+            	nogui = settings.getBoolean(VRConstants.SETTING_NO_GUI);
+    		}
+    	    
+            if (settings.get(VRConstants.SETTING_INSTANCE_RENDERING) != null){
+            	instanceVR = settings.getBoolean(VRConstants.SETTING_INSTANCE_RENDERING);
+    		}
+
+            if (settings.get(VRConstants.SETTING_DEFAULT_FOV) != null){
+            	defaultFOV = settings.getFloat(VRConstants.SETTING_DEFAULT_FOV);
+    		}
+            
+            if (settings.get(VRConstants.SETTING_DEFAULT_ASPECT_RATIO) != null){
+            	defaultAspect = settings.getFloat(VRConstants.SETTING_DEFAULT_ASPECT_RATIO);
+    		}
+            
+            if (settings.get(VRConstants.SETTING_VRAPI) != null){
+            	vrBinding = settings.getInteger(VRConstants.SETTING_VRAPI);
+    		}
+            
+    	}
+    }
+}

+ 1534 - 0
jme3-vr/src/main/java/com/jme3/app/VRApplication.java

@@ -0,0 +1,1534 @@
+package com.jme3.app;
+
+import com.jme3.app.AppTask;
+import com.jme3.app.Application;
+import com.jme3.app.LegacyApplication;
+import com.jme3.app.LostFocusBehavior;
+import com.jme3.app.ResetStatsState;
+import com.jme3.app.SimpleApplication;
+import com.jme3.app.state.AppState;
+import com.jme3.app.state.AppStateManager;
+import com.jme3.asset.AssetManager;
+import com.jme3.audio.AudioContext;
+import com.jme3.audio.AudioRenderer;
+import com.jme3.audio.Listener;
+import com.jme3.input.InputManager;
+import com.jme3.input.JoyInput;
+import com.jme3.input.KeyInput;
+import com.jme3.input.MouseInput;
+import com.jme3.input.TouchInput;
+import com.jme3.input.controls.KeyTrigger;
+import com.jme3.input.vr.OSVR;
+import com.jme3.input.vr.OpenVR;
+import com.jme3.input.vr.VRAPI;
+import com.jme3.input.vr.VRInputAPI;
+import com.jme3.math.ColorRGBA;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Vector3f;
+import com.jme3.post.PreNormalCaching;
+import com.jme3.profile.AppProfiler;
+import com.jme3.renderer.Camera;
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.Renderer;
+import com.jme3.renderer.ViewPort;
+import com.jme3.renderer.queue.RenderQueue.Bucket;
+import com.jme3.scene.Node;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.Spatial.CullHint;
+import com.jme3.system.AppSettings;
+import com.jme3.system.JmeContext;
+import com.jme3.system.JmeContext.Type;
+import com.jme3.system.jopenvr.JOpenVRLibrary;
+import com.jme3.system.JmeSystem;
+import com.jme3.system.NanoTimer;
+import com.jme3.system.SystemListener;
+import com.jme3.system.Timer;
+import com.jme3.system.lwjgl.LwjglDisplayVR;
+import com.jme3.system.lwjgl.LwjglOffscreenBufferVR;
+
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Locale;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.Future;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import jmevr.util.VRViewManager;
+import jmevr.util.VRGuiManager;
+import jmevr.util.VRGuiManager.POSITIONING_MODE;
+import jmevr.util.VRMouseManager;
+
+import org.lwjgl.system.Platform;
+
+
+/**
+ * A JMonkey application dedicated to Virtual Reality. An application that use VR devices (HTC vive, ...) has to extends this one.<br>
+ * @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 abstract class VRApplication implements Application, SystemListener {
+
+	
+    private static final Logger logger = Logger.getLogger(LegacyApplication.class.getName());
+
+    /**
+     * The default FOV.
+     */
+    public float DEFAULT_FOV    = 108f;
+    
+    
+    /**
+     * The default aspect ratio.
+     */
+    public float DEFAULT_ASPECT = 1f;
+    
+    /**
+     * Is the application is based on OSVR (default is <code>false</code>).
+     */
+    public boolean CONSTRUCT_WITH_OSVR = false;
+    
+    /**
+     * Is the application has not to start within VR mode (default is <code>false</code>).
+     */
+    public boolean DISABLE_VR = false;
+    
+    /**
+     * VR application configuration parameters.
+     * @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 static enum PreconfigParameter {
+    	/**
+    	 * Is the SteamVR compositor is used (kinda needed at the moment)
+    	 */
+        USE_VR_COMPOSITOR, 
+        
+        /**
+         * Render two eyes, regardless of VR API detection.
+         */
+        FORCE_VR_MODE, 
+        
+        /**
+         * Invert the eyes.
+         */
+        FLIP_EYES,
+        
+        /**
+         * Show GUI even if it is behind objects.
+         */
+        SET_GUI_OVERDRAW, 
+        
+        /**
+         * 
+         */
+        SET_GUI_CURVED_SURFACE, 
+        
+        /**
+         * Display a mirror rendering on the screen. Runs faster when set to <code>false</code>.
+         */
+        ENABLE_MIRROR_WINDOW, 
+        
+        /**
+         * 
+         */
+        PREFER_OPENGL3, 
+        
+        /**
+         * Disable VR rendering, regardless VR API and devices are presents.
+         */
+        DISABLE_VR,
+        
+        /**
+         * 
+         */
+        SEATED_EXPERIENCE, 
+        
+        /**
+         * Remove GUI node from the application.
+         */
+        NO_GUI, 
+        
+        /**
+         * Faster VR rendering, requires some vertex shader changes (see Common/MatDefs/VR/Unshaded.j3md)
+         */
+        INSTANCE_VR_RENDERING, 
+        
+        /**
+         * 
+         */
+        FORCE_DISABLE_MSAA
+    }
+    
+    private VRAPI VRhardware            = null;
+    private VRGuiManager guiManager     = null;
+    private VRMouseManager mouseManager = null;
+    private VRViewManager viewmanager   = null;
+    
+    private String OS;
+     
+    private Camera dummyCam;
+    private Spatial observer;
+    private boolean VRSupportedOS;
+    private boolean forceVR;
+    private boolean disableSwapBuffers = true;
+    private boolean tryOpenGL3 = true;
+    private boolean seated;
+    private boolean nogui;
+    private boolean instanceVR;
+    private boolean forceDisableMSAA;
+    
+    // things taken from LegacyApplication
+    private AppStateManager stateManager;    
+    private Camera cam;    
+    private AppSettings settings;
+    private JmeContext context;    
+    private float speed = 1f;
+    private AudioRenderer audioRenderer;    
+    private LostFocusBehavior lostFocusBehavior = LostFocusBehavior.ThrottleOnLostFocus;
+    private final ConcurrentLinkedQueue<AppTask<?>> taskQueue = new ConcurrentLinkedQueue<AppTask<?>>();
+    private Timer timer = new NanoTimer();
+    private boolean paused = false, inputEnabled = true;
+    private InputManager inputManager;
+    private RenderManager renderManager;    
+    private ViewPort viewPort;
+    private ViewPort guiViewPort;
+    private AssetManager assetManager;
+    private Renderer renderer;
+    private Listener listener;
+    private MouseInput mouseInput;
+    private KeyInput keyInput;
+    private JoyInput joyInput;
+    private TouchInput touchInput;
+
+    protected Node guiNode, rootNode;
+    
+    private float fFar = 1000f, fNear = 1f;
+    private int xWin = 1280, yWin = 720;
+    
+    private float resMult = 1f;
+    
+    private boolean useCompositor = true, compositorOS;
+    private final String RESET_HMD = "ResetHMD";  
+    
+    /**
+     * Create a new VR application and attach the given {@link AppState app states}.<br>
+     * The application scene is made of a {@link #getRootNode() root node} that holds the scene spatials 
+     * and a {@link #getGuiNode() GUI node} that is the root of the Graphical user interface.
+     * @param initialStates the {@link AppState app states} to attach to the application.
+     */
+    public VRApplication(AppState... initialStates) {
+        this();
+        
+        if (initialStates != null) {
+            for (AppState a : initialStates) {
+                if (a != null) {
+                    stateManager.attach(a);
+                }
+            }
+        }
+    }
+    
+    /**
+     * Create a new VR application.<br> 
+     * The application scene is made of a {@link #getRootNode() root node} that holds the scene spatials 
+     * and a {@link #getGuiNode() GUI node} that is the root of the Graphical user interface.
+     */
+    public VRApplication() {
+        super();
+        
+        rootNode = new Node("root");
+        guiNode = new Node("guiNode");
+        
+        guiNode.setQueueBucket(Bucket.Gui);
+        guiNode.setCullHint(CullHint.Never);
+        dummyCam = new Camera();
+        
+        initStateManager();
+        
+        // Create the GUI manager.
+        guiManager = new VRGuiManager();
+        
+        // Create a new view manager.
+        viewmanager = new VRViewManager();
+        
+        // Create a new mouse manager.
+        mouseManager = new VRMouseManager();
+        
+        // we are going to use OpenVR now, not the Oculus Rift
+        // OpenVR does support the Rift
+        OS = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH);
+        VRSupportedOS = !OS.contains("nux") && System.getProperty("sun.arch.data.model").equalsIgnoreCase("64"); //for the moment, linux/unix causes crashes, 64-bit only
+        compositorOS = OS.contains("indows");
+        
+        if( !VRSupportedOS ) {
+        	logger.warning("Non-supported OS: " + OS + ", architecture: " + System.getProperty("sun.arch.data.model"));
+        } else if( DISABLE_VR ) {
+        	logger.warning("VR disabled via code.");
+        } else if( VRSupportedOS && DISABLE_VR == false ) {
+            if( CONSTRUCT_WITH_OSVR ) {
+            	//FIXME: WARNING !!
+                VRhardware = new OSVR(null);
+                logger.config("Creating OSVR wrapper [SUCCESS]");
+            } else {
+            	//FIXME: WARNING !!
+                VRhardware = new OpenVR(null);
+                logger.config("Creating OpenVR wrapper [SUCCESS]");
+            }
+            if( VRhardware.initialize() ) {
+                setPauseOnLostFocus(false);
+            }
+        }
+    }
+    
+    /**
+     * Get the VR underlying hardware.
+     * @return the VR underlying hardware.
+     */
+    public VRAPI getVRHardware() {
+        return VRhardware;
+    }
+    
+    /**
+     * Get the VR dedicated input.
+     * @return the VR dedicated input.
+     */
+    public VRInputAPI getVRinput() {
+        if( VRhardware == null ) return null;
+        return VRhardware.getVRinput();
+    }
+    
+    /**
+     * Get the VR view manager.
+     * @return the VR view manager.
+     */
+    public VRViewManager getVRViewManager() {
+        return viewmanager;
+    }
+    
+    /**
+     * Get the GUI manager attached to this application.
+     * @return the GUI manager attached to this application.
+     */
+    public VRGuiManager getVRGUIManager(){
+    	return guiManager;
+    }
+    
+    /**
+     * Get the VR mouse manager attached to this application.
+     * @return the VR mouse manager attached to this application.
+     */
+    public VRMouseManager getVRMouseManager(){
+    	return mouseManager;
+    }
+    
+    /**
+     * Set the frustrum values for the application.
+     * @param near the frustrum near value.
+     * @param far the frustrum far value.
+     */
+    public void setFrustrumNearFar(float near, float far) {
+        fNear = near;
+        fFar = far;
+    }
+    
+    /**
+     * Set the mirror window size in pixel.
+     * @param width the width of the mirror window in pixel.
+     * @param height the height of the mirror window in pixel.
+     */
+    public void setMirrorWindowSize(int width, int height) {
+        xWin = width;
+        yWin = height;
+    }
+    
+    /**
+     * Set the resolution multiplier.
+     * @param val the resolution multiplier.
+     */
+    public void setResolutionMultiplier(float val) {
+        resMult = val;
+        if( viewmanager != null ) viewmanager.setResolutionMultiplier(resMult);
+    }
+    
+    
+    /**
+     * Is the SteamVR compositor is active.
+     * @return <code>true</code> if the SteamVR compositor is active and <code>false</code> otherwise.
+     */
+    public boolean compositorAllowed() {
+        return useCompositor && compositorOS;
+    }
+    
+    /**
+     * Get if the system currently support VR.
+     * @return <code>true</code> if the system currently support VR and <code>false</Code> otherwise.
+     */
+    public boolean isOSVRSupported() {
+        return VRSupportedOS;
+    }
+    
+    /**
+     * Simple update of the application, this method should contains {@link #getRootNode() root node} updates.
+     * This method is called by the {@link #update() update()} method and should not be called manually.
+     * @param tpf the application time.
+     */
+    public void simpleUpdate(float tpf) {   }
+    
+    /**
+     * Rendering callback of the application. This method is called by the {@link #update() update()} method and should not be called manually.
+     * @param renderManager the {@link RenderManager render manager}.
+     */
+    public void simpleRender(RenderManager renderManager) {
+        PreNormalCaching.resetCache(isInVR());
+    }
+
+    
+    /*
+        we do NOT want to get & modify the distortion scene camera, so
+        return the left viewport camera instead if we are in VR mode
+    */
+    @Override
+    public Camera getCamera() {
+        if( isInVR() && viewmanager != null && viewmanager.getLeftCamera() != null ) {
+            return dummyCam;
+        }
+        return cam;
+    }
+    
+    /**
+     * Get the application internal camera.
+     * @return the application internal camera.
+     * @see #getCamera()
+     */
+    public Camera getBaseCamera() {
+        return cam;
+    }
+ 
+
+    @Override
+    public JmeContext getContext(){
+        return context;
+    }
+
+    @Override
+    public AssetManager getAssetManager(){
+        return assetManager;
+    }
+
+    @Override
+    public InputManager getInputManager(){
+        return inputManager;
+    }
+
+    @Override
+    public AppStateManager getStateManager() {
+        return stateManager;
+    }
+
+    @Override
+    public RenderManager getRenderManager() {
+        return renderManager;
+    }
+
+    @Override
+    public Renderer getRenderer(){
+        return renderer;
+    }
+
+    @Override
+    public AudioRenderer getAudioRenderer() {
+        return audioRenderer;
+    }
+
+    @Override
+    public Listener getListener() {
+        return listener;
+    }
+    
+    @Override
+    public Timer getTimer(){
+        return timer;
+    }    
+
+    /**
+     * Handle the error given in parameters by creating a log entry and a dialog window. Internal use only.
+     */
+    public void handleError(String errMsg, Throwable t){
+        // Print error to log.
+        logger.log(Level.SEVERE, errMsg, t);
+        // Display error message on screen if not in headless mode
+        if (context.getType() != JmeContext.Type.Headless) {
+            if (t != null) {
+                JmeSystem.showErrorDialog(errMsg + "\n" + t.getClass().getSimpleName() +
+                        (t.getMessage() != null ? ": " +  t.getMessage() : ""));
+            } else {
+                JmeSystem.showErrorDialog(errMsg);
+            }
+        }
+
+        stop(); // stop the application
+    }
+
+
+    /**
+     * Force the focus gain for the application. Internal use only.
+     */
+    public void gainFocus(){
+        if (lostFocusBehavior != LostFocusBehavior.Disabled) {
+            if (lostFocusBehavior == LostFocusBehavior.PauseOnLostFocus) {
+                paused = false;
+            }
+            context.setAutoFlushFrames(true);
+            if (inputManager != null) {
+                inputManager.reset();
+            }
+        }
+    }
+    
+    /**
+     * Force the focus lost for the application. Internal use only.
+     */
+    public void loseFocus(){
+        if (lostFocusBehavior != LostFocusBehavior.Disabled){
+            if (lostFocusBehavior == LostFocusBehavior.PauseOnLostFocus) {
+                paused = true;
+            }
+            context.setAutoFlushFrames(false);
+        }
+    }
+    
+    /**
+     * Reshape the display window. Internal use only.
+     */
+    public void reshape(int w, int h){
+        if (renderManager != null) {
+            renderManager.notifyReshape(w, h);
+        }
+    }    
+
+    /**
+     * Request the application to close. Internal use only.
+     */
+    public void requestClose(boolean esc){
+        context.destroy(false);
+    }
+    
+    /**
+     * Set the {@link AppSettings display settings} to define the display created.
+     * <p>
+     * Examples of display parameters include display frame {@link AppSettings#getWidth() width} and {@link AppSettings#getHeight() height},
+     * pixel {@link AppSettings#getBitsPerPixel() color bit depth}, {@link AppSettings#getDepthBits() z-buffer bits}, {@link AppSettings#getSamples() anti-aliasing samples}, {@link AppSettings#getFrequency() update frequency}, ...
+     * <br><br>If this method is called while the application is already running, then
+     * {@link #restart() } must be called to apply the settings to the display.
+     *
+     * @param settings The settings to set.
+     */
+    public void setSettings(AppSettings settings){
+        this.settings = settings;
+        if (context != null && settings.useInput() != inputEnabled){
+            // may need to create or destroy input based
+            // on settings change
+            inputEnabled = !inputEnabled;
+            if (inputEnabled){
+                initInput();
+            }else{
+                destroyInput();
+            }
+        }else{
+            inputEnabled = settings.useInput();
+        }
+    }    
+    
+    /**
+     * Sets the {@link Timer} implementation that will be used for calculating
+     * frame times.<br><br>
+     * By default, Application will use the Timer as returned by the current {@link JmeContext} implementation.
+     * @param timer the timer to use.
+     */
+    public void setTimer(Timer timer){
+        this.timer = timer;
+
+        if (timer != null) {
+            timer.reset();
+        }
+
+        if (renderManager != null) {
+            renderManager.setTimer(timer);
+        }
+    }
+    
+
+    /**
+     * Determine the application's behavior when unfocused.
+     * @return The lost focus behavior of the application.
+     */
+    public LostFocusBehavior getLostFocusBehavior() {
+        return lostFocusBehavior;
+    }
+
+    /**
+     * Change the application's behavior when unfocused. By default, the application will
+     * {@link LostFocusBehavior#ThrottleOnLostFocus throttle the update loop}
+     * so as to not take 100% CPU usage when it is not in focus, e.g.
+     * alt-tabbed, minimized, or obstructed by another window.
+     *
+     * @param lostFocusBehavior The new {@link LostFocusBehavior lost focus behavior} to use.
+     */
+    public void setLostFocusBehavior(LostFocusBehavior lostFocusBehavior) {
+        this.lostFocusBehavior = lostFocusBehavior;
+    }
+
+    /**
+     * Get if the application has to pause then it lost the focus.
+     * @return <code>true</code> if pause on lost focus is enabled, <code>false</code> otherwise.
+     * @see #getLostFocusBehavior()
+     */
+    public boolean isPauseOnLostFocus() {
+        return getLostFocusBehavior() == LostFocusBehavior.PauseOnLostFocus;
+    }
+
+    /**
+     * Enable or disable pause on lost focus.
+     * <p>
+     * By default, pause on lost focus is enabled.
+     * If enabled, the application will stop updating
+     * when it loses focus or becomes inactive (e.g. alt-tab).
+     * For online or real-time applications, this might not be preferable,
+     * so this feature should be set to disabled. For other applications,
+     * it is best to keep it on so that CPU usage is not used when
+     * not necessary.
+     *
+     * @param pauseOnLostFocus <code>true</code> to enable pause on lost focus, <code>false</code>
+     * otherwise.
+     *
+     * @see #setLostFocusBehavior(com.jme3.app.LostFocusBehavior)
+     */
+    public void setPauseOnLostFocus(boolean pauseOnLostFocus) {
+        if (pauseOnLostFocus) {
+            setLostFocusBehavior(LostFocusBehavior.PauseOnLostFocus);
+        } else {
+            setLostFocusBehavior(LostFocusBehavior.Disabled);
+        }
+    }    
+    
+    @Override
+    public void start() {
+    	
+    	logger.config("Starting application...");
+    	
+        // set some default settings in-case
+        // settings dialog is not shown
+        boolean loadSettings = false;
+        if (settings == null) {
+            setSettings(new AppSettings(true));
+            loadSettings = true;
+        }
+        
+        GraphicsDevice defDev = null;
+		try {
+			GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
+			defDev = ge.getDefaultScreenDevice();
+		} catch (Throwable e1) {
+			logger.log(Level.SEVERE, "Cannot access default screen device: "+e1.getMessage(), e1);
+		}
+		
+        if( isInVR() && !compositorAllowed() ) {
+        	logger.warning("VR Composition is not allowed.");
+            // "easy extended" mode
+            // TO-DO: JFrame was removed in LWJGL 3, need to use new GLFW library to pick "monitor" display of VR device
+            // first, find the VR device
+            GraphicsDevice VRdev = null;
+            GraphicsDevice[] devs = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
+            // pick the display that isn't the default one
+            for(GraphicsDevice gd : devs) {
+                if( gd != defDev ) {
+                    VRdev = gd;
+                    break;
+                }
+            }
+            // did we get the VR device?
+            if( VRdev != null ) {
+                // set properties for VR acceleration
+                try {   
+                    java.awt.DisplayMode useDM = null;
+                    int max = 0;
+                    for(java.awt.DisplayMode dm : VRdev.getDisplayModes()) {
+                        int check = dm.getHeight() + dm.getWidth() + dm.getRefreshRate() + dm.getBitDepth();
+                        if( check > max ) {
+                            max = check;
+                            useDM = dm;
+                        }
+                    }
+                    // create a window for the VR device
+                    settings.setWidth(useDM.getWidth());
+                    settings.setHeight(useDM.getHeight());
+                    settings.setBitsPerPixel(useDM.getBitDepth());
+                    settings.setFrequency(useDM.getRefreshRate());
+                    settings.setSwapBuffers(true);
+                    settings.setVSync(true); // allow vsync on this display
+                    setSettings(settings);
+                    //VRdev.setFullScreenWindow(VRwindow);
+                    // make sure we are in the right display mode
+                    if( VRdev.getDisplayMode().equals(useDM) == false ) {
+                        VRdev.setDisplayMode(useDM);
+                    }
+                    // make a blank cursor to hide it
+                    //BufferedImage cursorImg = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
+                    //Cursor blankCursor = Toolkit.getDefaultToolkit().createCustomCursor(cursorImg, new Point(0, 0), "blank cursor");                    
+                    //VRwindow.setCursor(blankCursor);
+                    //jmeCanvas.getCanvas().setCursor(blankCursor);
+                    //VRwindow.pack();
+                    //VRwindow.setVisible(true);
+                    //startCanvas();
+                    logger.config("Starting application [SUCCESS]");
+                    return;
+                } catch(Exception e) { 
+                	logger.log(Level.SEVERE, "Error during application start: "+e.getMessage(), e);
+                }
+            }
+        }
+        
+        if( !isInVR() ) {
+        	
+        	logger.config("VR mode disabled.");
+        	
+            // not in VR, show settings dialog
+            if( Platform.get() != Platform.MACOSX ) {
+                if (!JmeSystem.showSettingsDialog(settings, loadSettings)) {
+                	logger.config("Starting application [SUCCESS]");
+                    return;
+                }            
+            } else {
+                // GLFW workaround on macs
+                settings.setFrequency(defDev.getDisplayMode().getRefreshRate());
+                settings.setDepthBits(24);
+                settings.setVSync(true);
+                // try and read resolution from file in local dir
+                File resfile = new File("resolution.txt");
+                if( resfile.exists() ) {
+                    try {
+                        BufferedReader br = new BufferedReader(new FileReader(resfile));
+                        settings.setWidth(Integer.parseInt(br.readLine()));
+                        settings.setHeight(Integer.parseInt(br.readLine()));
+                        try {
+                            settings.setFullscreen(br.readLine().toLowerCase(Locale.ENGLISH).contains("full"));
+                        } catch(Exception e) {
+                            settings.setFullscreen(false);
+                        }
+                        br.close();
+                    } catch(Exception e) {
+                        settings.setWidth(1280);
+                        settings.setHeight(720);
+                    }
+                } else {
+                    settings.setWidth(1280);
+                    settings.setHeight(720);
+                    settings.setFullscreen(false);
+                }
+                settings.setResizable(false);
+            }
+            settings.setSwapBuffers(true);
+        } else {
+        	
+        	logger.config("VR mode enabled.");
+        	
+            // use basic mirroring window, skip settings window
+            settings.setWidth(xWin);
+            settings.setHeight(yWin);
+            settings.setBitsPerPixel(24);     
+            settings.setFrameRate(0); // never sleep in main loop
+            settings.setFrequency(VRhardware.getDisplayFrequency());
+            settings.setFullscreen(false);
+            settings.setVSync(false); // stop vsyncing on primary monitor!
+            settings.setSwapBuffers(!disableSwapBuffers || VRhardware instanceof OSVR);
+            settings.setTitle("Put Headset On Now: " + settings.getTitle());
+            settings.setResizable(true);
+        }
+        
+        if( forceDisableMSAA ) {
+        	logger.config("Disabling multisampling.");
+            // disable multisampling, which is more likely to break things than be useful
+            settings.setSamples(1);
+        }
+        
+        // set opengl mode
+        if( tryOpenGL3 ) {
+        	logger.config("Using LWJGL OpenGL 3 renderer.");
+            settings.setRenderer(AppSettings.LWJGL_OPENGL3);
+        } else {
+        	logger.config("Using LWJGL OpenGL 2 renderer.");
+            settings.setRenderer(AppSettings.LWJGL_OPENGL2);
+        }
+
+        
+        setSettings(settings);     
+        start(JmeContext.Type.Display, false);
+        
+        // disable annoying warnings about GUI stuff being updated, which is normal behavior
+        // for late GUI placement for VR purposes
+        Logger.getLogger("com.jme3").setLevel(Level.SEVERE);        
+    }    
+    
+    /**
+     * Starts the application in {@link com.jme3.system.JmeContext.Type#Display display} mode.
+     * @param waitFor if <code>true</code>, the method will wait until the application is started.
+     * @see #start(com.jme3.system.JmeContext.Type, boolean)
+     */
+    public void start(boolean waitFor){
+        start(JmeContext.Type.Display, waitFor);
+    }   
+    
+    /**
+     * Starts the application.
+     * Creating a rendering context and executing the main loop in a separate thread.
+     * @param contextType the {@link com.jme3.system.JmeContext.Type type} of the context to create.
+     * @param waitFor if <code>true</code>, the method will wait until the application is started.
+     * @throws IllegalArgumentException if the context type is not supported.
+     */
+    public void start(JmeContext.Type contextType, boolean waitFor){
+        if (context != null && context.isCreated()){
+            logger.warning("start() called when application already created!");
+            return;
+        }
+
+        if (settings == null){
+            settings = new AppSettings(true);
+        }
+
+        logger.log(Level.FINE, "Starting application: {0}", getClass().getName());
+        
+        // Create VR decicated context
+        if (contextType == Type.Display){
+          context = new LwjglDisplayVR();
+          context.setSettings(settings);
+        } else if (contextType == Type.OffscreenSurface){
+          context = new LwjglOffscreenBufferVR();
+          context.setSettings(settings);
+        } else {
+          logger.severe("Unsupported context type \""+contextType+"\". Supported are \"Display\" and \"OffscreenSurface\"");
+          throw new IllegalArgumentException("Unsupported context type \""+contextType+"\". Supported are \"Display\" and \"OffscreenSurface\"");
+        }
+
+        context.setSystemListener(this);
+        context.create(waitFor);
+    }    
+    
+    /**
+     * Move filters from the main scene into the eye's.
+     * This removes filters from the main scene.
+     */
+    public void moveScreenProcessingToVR() {
+        if( isInVR() ) {
+        	viewmanager.moveScreenProcessingToEyes();
+        }
+    }
+    
+    /**
+     * Set VR application {@link PreconfigParameter specific parameter}.
+     * If making changes to default values, this must be called before the VRApplication starts
+     * @param parm the parameter to set.
+     * @param value the value of the parameter.
+     */
+    public void preconfigureVRApp(PreconfigParameter parm, boolean value) {        
+        switch( parm ) {
+            case SET_GUI_OVERDRAW:
+                guiManager._enableGuiOverdraw(value);
+                break;
+            case SET_GUI_CURVED_SURFACE:
+            	guiManager._enableCurvedSuface(value);
+                break;
+            case FORCE_VR_MODE:
+                forceVR = value;
+                break;
+            //case USE_CUSTOM_DISTORTION: //deprecated, always using a render manager
+            //    VRViewManager._setCustomDistortion(value);
+            //    break;
+            case USE_VR_COMPOSITOR:
+                useCompositor = value;
+                if( value == false ) disableSwapBuffers = false;
+                break;
+            case FLIP_EYES:
+                if( VRhardware == null ) return;
+                VRhardware._setFlipEyes(value);
+                break;
+            case INSTANCE_VR_RENDERING:
+                instanceVR = value;
+                break;
+            case ENABLE_MIRROR_WINDOW:
+                if( useCompositor == false ) {
+                    disableSwapBuffers = false;
+                } else disableSwapBuffers = !value;
+                break;
+            case PREFER_OPENGL3:
+                tryOpenGL3 = value;
+                break;
+            case DISABLE_VR:
+                DISABLE_VR = value;
+                break;
+            case NO_GUI:
+                nogui = value;
+                break;
+            case SEATED_EXPERIENCE:
+                seated = value;
+                break;
+            case FORCE_DISABLE_MSAA:
+                forceDisableMSAA = value;
+                break;
+        }
+    }
+    
+    /**
+     * Can be used to change seated experience during runtime.
+     * @param isSeated <code>true</code> if designed for sitting, <code>false</code> for standing/roomscale
+     * @see #isSeatedExperience()
+     */
+    public void setSeatedExperience(boolean isSeated) {
+        seated = isSeated;
+        if( VRhardware instanceof OpenVR ) {
+            if( VRhardware.getCompositor() == null ) return;
+            if( seated ) {
+                ((OpenVR)VRhardware).getCompositor().SetTrackingSpace.apply(JOpenVRLibrary.ETrackingUniverseOrigin.ETrackingUniverseOrigin_TrackingUniverseSeated);
+            } else {
+                ((OpenVR)VRhardware).getCompositor().SetTrackingSpace.apply(JOpenVRLibrary.ETrackingUniverseOrigin.ETrackingUniverseOrigin_TrackingUniverseStanding);                
+            }        
+        }
+    }
+    
+    /**
+     * Check if the application is configured as a seated experience.
+     * @return <code>true</code> if the application is configured as a seated experience and <code>false</code> otherwise.
+     * @see #setSeatedExperience(boolean)
+     */
+    public boolean isSeatedExperience() {
+        return seated;
+    }
+    
+    /**
+     * Reset headset pose if seating experience.
+     */
+    public void resetSeatedPose(){
+        if( VRSupportedOS == false || isSeatedExperience() == false ) return;
+        VRhardware.reset();
+    }
+    
+    /**
+     * Check if the rendering is instanced (see <a href="https://en.wikipedia.org/wiki/Geometry_instancing">Geometry instancing</a>).
+     * @return <code>true</code> if the rendering is instanced and <code>false</code> otherwise.
+     */
+    public boolean isInstanceVRRendering() {
+        return instanceVR && isInVR();
+    }
+    
+    /**
+     * Check if the VR mode is enabled.
+     * @return <code>true</code> if the VR mode is enabled and <code>false</code> otherwise.
+     */
+    public boolean isInVR() {
+        return DISABLE_VR == false && (forceVR || VRSupportedOS && VRhardware != null && VRhardware.isInitialized());
+    }  
+
+    
+    /**
+     * Get the GUI node from the application.
+     * @return the GUI node from the application.
+     * @see #setGuiNode(Node)
+     */
+    public Node getGuiNode(){
+        return guiNode;
+    }
+    
+    /**
+     * Set the GUI node that is displayed within the GUI viewport. 
+     * Calling this method involve clearing all the scenes previously attached to the gui viewport.
+     * @param node the GUI node to attach.
+     * @see #getGuiNode()
+     */
+    public void setGuiNode(Node node){
+    	if (node != null){
+    		if (guiViewPort != null){
+        		  
+                enqueue(new Callable<Object>(){
+
+				  @Override
+				  public Object call() throws Exception {
+				    guiViewPort.clearScenes();
+				    guiViewPort.attachScene(node);
+					guiNode = node;
+					return null;
+				  }
+        			  
+        		});
+
+        	} else {
+        		throw new IllegalArgumentException("GUI view port is not initialized.");
+        	}
+    	}
+    	
+    }
+    
+    /**
+     * Get the root node of the application.
+     * @return the root node of the application.
+     */
+    public Node getRootNode() {
+        return rootNode;
+    }
+    
+    /**
+     * Check if the application has a GUI overlay attached.
+     * @return <code>true</code> if the application has a GUI overlay attached and <code>false</code> otherwise.
+     */
+    public boolean hasTraditionalGUIOverlay() {
+        return !nogui;
+    }
+
+
+    /**
+     * Get the scene observer. If no observer has been set, this method return the application {@link #getCamera() camera}.
+     * @return the scene observer. 
+     * @see #setObserver(Spatial)
+     */
+    public Object getObserver() {
+        if( observer == null ) {
+            return getCamera();
+        }
+        return observer;
+    }
+    
+    /**
+     * Set the scene observer. The VR headset will be linked to it. If no observer is set, the VR headset is linked to the the application {@link #getCamera() camera}.
+     * @param observer the scene observer.
+     */
+    public void setObserver(Spatial observer) {
+       this.observer = observer;
+    }
+    
+    /*
+        where is the headset pointing, after all rotations are combined?
+        depends on observer rotation, if any
+    */
+    private static Quaternion tempq = new Quaternion();
+    
+    /**
+     * Get the observer final rotation within the scene.
+     * @return the observer final rotation within the scene.
+     * @see #getFinalObserverPosition()
+     */
+    public Quaternion getFinalObserverRotation() {
+        if( viewmanager == null ) {
+            if( observer == null ) {
+                return getCamera().getRotation();
+            } else return observer.getWorldRotation();
+        }        
+        if( observer == null ) {
+            tempq.set(dummyCam.getRotation());
+        } else {
+            tempq.set(observer.getWorldRotation());
+        }
+        return tempq.multLocal(VRhardware.getOrientation());
+    }
+    
+    /**
+     * Get the observer final position within the scene.
+     * @return the observer position.
+     * @see #getFinalObserverRotation()
+     */
+    public Vector3f getFinalObserverPosition() {
+        if( viewmanager == null ) {
+            if( observer == null ) {
+                return getCamera().getLocation();
+            } else return observer.getWorldTranslation();            
+        }
+        Vector3f pos = VRhardware.getPosition();
+        if( observer == null ) {
+            dummyCam.getRotation().mult(pos, pos);
+            return pos.addLocal(dummyCam.getLocation());
+        } else {
+            observer.getWorldRotation().mult(pos, pos);
+            return pos.addLocal(observer.getWorldTranslation());
+        }
+    }
+    
+    /**
+     * Set the VR headset height from the ground.
+     * @param amount the VR headset height from the ground.
+     * @see #getVRHeightAdjustment()
+     */
+    public void setVRHeightAdjustment(float amount) {
+        if( viewmanager != null ) viewmanager.setHeightAdjustment(amount);
+    }
+    
+    /**
+     * Get the VR headset height from the ground.
+     * @return the VR headset height from the ground.
+     * @see #setVRHeightAdjustment(float)
+     */
+    public float getVRHeightAdjustment() {
+        if( viewmanager != null ) return viewmanager.getHeightAdjustment();
+        return 0f;
+    }
+      
+    /**
+     * Get the VR headset left viewport.
+     * @return the VR headset left viewport.
+     * @see #getRightViewPort()
+     */
+    public ViewPort getLeftViewPort() {
+        if( viewmanager == null ) return getViewPort();
+        return viewmanager.getLeftViewport();
+    }
+    
+    /**
+     * Get the VR headset right viewport.
+     * @return the VR headset right viewport.
+     * @see #getLeftViewPort()
+     */
+    public ViewPort getRightViewPort() {
+        if( viewmanager == null ) return getViewPort();
+        return viewmanager.getRightViewport();
+    }
+    
+    
+    /**
+     * Set the background color for both left and right view ports.
+     * @param clr the background color.
+     */
+    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);
+        }
+    }
+    
+
+    /**
+     * Runs tasks enqueued via {@link #enqueue(Callable)}
+     */
+    protected void runQueuedTasks() {
+	  AppTask<?> task;
+        while( (task = taskQueue.poll()) != null ) {
+            if (!task.isCancelled()) {
+                task.invoke();
+            }
+        }
+    }
+    
+    @Override
+    public void update() {    
+        // Make sure the audio renderer is available to callables
+        AudioContext.setAudioRenderer(audioRenderer);
+
+        runQueuedTasks();
+
+        if (speed != 0 && !paused) {
+
+            timer.update();
+
+            if (inputEnabled){
+                inputManager.update(timer.getTimePerFrame());
+            }
+
+            if (audioRenderer != null){
+                audioRenderer.update(timer.getTimePerFrame());
+            }
+        }
+        
+        if (speed == 0 || paused) {
+            try {
+                Thread.sleep(50); // throttle the CPU when paused
+            } catch (InterruptedException ex) {
+                Logger.getLogger(SimpleApplication.class.getName()).log(Level.SEVERE, null, ex);
+            }
+            return;
+        }
+        
+        float tpf = timer.getTimePerFrame() * speed;
+        
+        // update states
+        stateManager.update(tpf);
+
+        // simple update and root node
+        simpleUpdate(tpf);
+ 
+        
+        // render states
+        stateManager.render(renderManager);
+        
+        // update VR pose & cameras
+        if( viewmanager != null ) {
+        	viewmanager.update(tpf);    
+        } else if( observer != null ) {
+            getCamera().setFrame(observer.getWorldTranslation(), observer.getWorldRotation());
+        }
+        
+        //FIXME: check if this code is necessary.
+        // Updates scene and gui states.
+        rootNode.updateLogicalState(tpf);
+        guiNode.updateLogicalState(tpf);
+        
+        rootNode.updateGeometricState();
+        
+        if( isInVR() == false || guiManager.getPositioningMode() == POSITIONING_MODE.MANUAL ) {
+            // only update geometric state here if GUI is in manual mode, or not in VR
+            // it will get updated automatically in the viewmanager update otherwise
+            guiNode.updateGeometricState();
+        }
+        
+        renderManager.render(tpf, context.isRenderable());
+        simpleRender(renderManager);
+        stateManager.postRender();
+        
+        // update compositor?
+        if( viewmanager != null ) {
+        	viewmanager.sendTextures();
+        }
+    }
+
+    private void initAssetManager(){
+        URL assetCfgUrl = null;
+
+        if (settings != null){
+            String assetCfg = settings.getString("AssetConfigURL");
+            if (assetCfg != null){
+                try {
+                    assetCfgUrl = new URL(assetCfg);
+                } catch (MalformedURLException ex) {
+                }
+                if (assetCfgUrl == null) {
+                    assetCfgUrl = LegacyApplication.class.getClassLoader().getResource(assetCfg);
+                    if (assetCfgUrl == null) {
+                        logger.log(Level.SEVERE, "Unable to access AssetConfigURL in asset config:{0}", assetCfg);
+                        return;
+                    }
+                }
+            }
+        }
+        if (assetCfgUrl == null) {
+            assetCfgUrl = JmeSystem.getPlatformAssetConfigURL();
+        }
+        if (assetManager == null){
+            assetManager = JmeSystem.newAssetManager(assetCfgUrl);
+            logger.config("Created asset manager from "+assetCfgUrl);
+        }
+    }
+    
+
+    private void initDisplay(){
+        // aquire important objects
+        // from the context
+        settings = context.getSettings();
+
+        // Only reset the timer if a user has not already provided one
+        if (timer == null) {
+            timer = context.getTimer();
+        }
+
+        renderer = context.getRenderer();
+    }
+
+    private void initAudio(){
+        if (settings.getAudioRenderer() != null && context.getType() != JmeContext.Type.Headless){
+            audioRenderer = JmeSystem.newAudioRenderer(settings);
+            audioRenderer.initialize();
+            AudioContext.setAudioRenderer(audioRenderer);
+
+            listener = new Listener();
+            audioRenderer.setListener(listener);
+        }
+    }
+
+    /**
+     * Creates the camera to use for rendering. Default values are perspective
+     * projection with 45° field of view, with near and far values 1 and 1000
+     * units respectively.
+     */
+    private void initCamera(){
+        cam = new Camera(settings.getWidth(), settings.getHeight());
+
+        cam.setFrustumPerspective(45f, (float)cam.getWidth() / cam.getHeight(), 1f, 1000f);
+        cam.setLocation(new Vector3f(0f, 0f, 10f));
+        cam.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y);
+
+        renderManager = new RenderManager(renderer);
+        //Remy - 09/14/2010 setted the timer in the renderManager
+        renderManager.setTimer(timer);
+
+        viewPort = renderManager.createMainView("Default", cam);
+        viewPort.setClearFlags(true, true, true);
+
+        // Create a new cam for the gui
+        Camera guiCam = new Camera(settings.getWidth(), settings.getHeight());
+        guiViewPort = renderManager.createPostView("Gui Default", guiCam);
+        guiViewPort.setClearFlags(false, false, false);
+    }
+
+    /**
+     * Initializes mouse and keyboard input. Also
+     * initializes joystick input if joysticks are enabled in the
+     * AppSettings.
+     */
+    private void initInput(){
+        mouseInput = context.getMouseInput();
+        if (mouseInput != null)
+            mouseInput.initialize();
+
+        keyInput = context.getKeyInput();
+        if (keyInput != null)
+            keyInput.initialize();
+
+        touchInput = context.getTouchInput();
+        if (touchInput != null)
+            touchInput.initialize();
+
+        if (!settings.getBoolean("DisableJoysticks")){
+            joyInput = context.getJoyInput();
+            if (joyInput != null)
+                joyInput.initialize();
+        }
+
+        inputManager = new InputManager(mouseInput, keyInput, joyInput, touchInput);
+    }
+
+    private void initStateManager(){
+        stateManager = new AppStateManager(this);
+
+        // Always register a ResetStatsState to make sure
+        // that the stats are cleared every frame
+        stateManager.attach(new ResetStatsState());
+    }    
+
+    /**
+     * Do not call manually.
+     * Callback from ContextListener.
+     * <p>
+     * Initializes the <code>Application</code>, by creating a display and
+     * default camera. If display settings are not specified, a default
+     * 640x480 display is created. Default values are used for the camera;
+     * perspective projection with 45° field of view, with near
+     * and far values 1 and 1000 units respectively.
+     */
+    private void initialize_internal(){
+        if (assetManager == null){
+            initAssetManager();
+        }
+
+        initDisplay();
+        initCamera();
+
+        if (inputEnabled){
+            initInput();
+        }
+        initAudio();
+
+        // update timer so that the next delta is not too large
+//        timer.update();
+        timer.reset();
+
+        // user code here..
+    }
+    
+    @Override
+    public void initialize() {
+    	
+    	logger.config("Initialize VR application...");
+    	
+        initialize_internal();
+        cam.setFrustumFar(fFar);
+        cam.setFrustumNear(fNear);
+        dummyCam = cam.clone();
+        if( isInVR() ) {
+        	
+        	logger.config("VR mode enabled.");
+        	
+            if( VRhardware != null ) {
+                VRhardware.initVRCompositor(compositorAllowed());
+            } else {
+            	logger.warning("No VR system found.");
+            }
+            
+            //FIXME: WARNING !!
+            viewmanager = new VRViewManager();
+            viewmanager.setResolutionMultiplier(resMult);
+            inputManager.addMapping(RESET_HMD, new KeyTrigger(KeyInput.KEY_F9));
+            setLostFocusBehavior(LostFocusBehavior.Disabled);
+        } else {
+        	logger.config("VR mode disabled.");
+            viewPort.attachScene(rootNode);
+            guiViewPort.attachScene(guiNode);
+        }
+        
+        if( viewmanager != null ) {
+        	viewmanager.initialize();
+        }
+        
+        simpleInitApp();
+        
+        // any filters created, move them now
+        if( viewmanager != null ) {
+        	viewmanager.moveScreenProcessingToEyes();
+            
+            // print out camera information
+            if( isInVR() ) {
+                logger.info("VR Initialization Information");
+                if( viewmanager.getLeftCamera() != null ){ 
+                  logger.info("camLeft: " + viewmanager.getLeftCamera().toString());
+                }
+                
+                if( viewmanager.getRightCamera() != null ){ 
+                  logger.info("camRight: " + viewmanager.getRightCamera().toString());
+                }
+            }
+        }
+    }
+    
+    /**
+     * Initialize the application. This method has to be overridden by implementations.
+     */
+    public abstract void simpleInitApp();
+    
+    /**
+     * Destroy the application (release all resources).
+     */
+    public void destroy() {
+        if( VRhardware != null ) {
+            VRhardware.destroy();
+            VRhardware = null;
+        }        
+        DISABLE_VR = true;
+        stateManager.cleanup();
+
+        destroyInput();
+        if (audioRenderer != null)
+            audioRenderer.cleanup();
+
+        timer.reset();
+        Runtime.getRuntime().exit(0);
+    }
+    
+    protected void destroyInput(){
+        if (mouseInput != null)
+            mouseInput.destroy();
+
+        if (keyInput != null)
+            keyInput.destroy();
+
+        if (joyInput != null)
+            joyInput.destroy();
+
+        if (touchInput != null)
+            touchInput.destroy();
+
+        inputManager = null;
+    }
+    
+    @Override
+    public ViewPort getGuiViewPort() {
+        return guiViewPort;
+    }
+
+    @Override
+    public ViewPort getViewPort() {
+        return viewPort;
+    }
+    
+    @Override
+    public <V> Future<V> enqueue(Callable<V> callable) {
+        AppTask<V> task = new AppTask<V>(callable);
+        taskQueue.add(task);
+        return task;
+    }
+    
+    /**
+     * Enqueues a runnable object to execute in the jME3
+     * rendering thread.
+     * <p>
+     * Runnables are executed right at the beginning of the main loop.
+     * They are executed even if the application is currently paused
+     * or out of focus.
+     *
+     * @param runnable The runnable to run in the main jME3 thread
+     */
+    public void enqueue(Runnable runnable){
+        enqueue(new RunnableWrapper(runnable));
+    }
+
+    private class RunnableWrapper implements Callable<Object>{
+        private final Runnable runnable;
+
+        public RunnableWrapper(Runnable runnable){
+            this.runnable = runnable;
+        }
+
+        @Override
+        public Object call(){
+            runnable.run();
+            return null;
+        }
+
+    }    
+
+    /**
+     * Requests the context to close, shutting down the main loop
+     * and making necessary cleanup operations.
+     *
+     * Same as calling stop(false)
+     *
+     * @see #stop(boolean)
+     */
+    @Override
+    public void stop(){
+        stop(false);
+    }
+
+    /**
+     * Requests the context to close, shutting down the main loop
+     * and making necessary cleanup operations.
+     * After the application has stopped, it cannot be used anymore.
+     */
+    @Override
+    public void stop(boolean waitFor){
+        logger.log(Level.FINE, "Closing application: {0}", getClass().getName());
+        context.destroy(waitFor);
+    }
+
+    /**
+     * Restarts the context, applying any changed settings.
+     * <p>
+     * Changes to the {@link AppSettings} of this Application are not
+     * applied immediately; calling this method forces the context
+     * to restart, applying the new settings.
+     */
+    @Override
+    public void restart(){
+        context.setSettings(settings);
+        context.restart();
+    }
+
+    /**
+     * Sets an AppProfiler hook that will be called back for
+     * specific steps within a single update frame.  Value defaults
+     * to null.
+     */
+    
+    public void setAppProfiler(AppProfiler prof) {
+        return;
+    }
+
+    /**
+     * Returns the current AppProfiler hook, or null if none is set.
+     */
+    public AppProfiler getAppProfiler() {
+        return null;
+    }
+}

+ 147 - 0
jme3-vr/src/main/java/com/jme3/app/VRConstants.java

@@ -0,0 +1,147 @@
+package com.jme3.app;
+
+import java.util.HashMap;
+
+import com.jme3.system.AppSettings;
+
+/**
+ * Some constants dedicated to the VR module.
+ * @author Julien Seinturier - JOrigin project - <a href="http://www.jorigin.org">http:/www.jorigin.org</a>
+ * @since 3.1.0
+ */
+public class VRConstants {
+	
+	/**
+	 * An AppSettings parameter that set if the VR compositor has to be used.
+	 * <p>
+	 * <b>Type: </b><code>boolean</code><br>
+	 * <b>Usage: </b><code>{@link AppSettings appSettings}.{@link HashMap#put(Object, Object) put}(VRConstants.SETTING_USE_COMPOSITOR, value)</code>
+	 */
+    public static final String SETTING_USE_COMPOSITOR = "VRUseCompositor";
+    
+    /**
+     * An AppSettings parameter that set if the rendering has to use two eyes, 
+     * regardless of VR API detection (turning this setting on without a VR system should lead to errors).
+     * <p>
+	 * <b>Type: </b><code>boolean</code><br>
+	 * <b>Usage: </b><code>{@link AppSettings appSettings}.{@link HashMap#put(Object, Object) put}(VRConstants.SETTING_VR_FORCE, value)</code>
+
+     */
+    public static final String SETTING_VR_FORCE = "VRForce";
+    
+    /**
+     * An AppSettings parameter that set to invert the eyes of the HMD.
+     * <b>Type: </b><code>boolean</code><br>
+	 * <b>Usage: </b><code>{@link AppSettings appSettings}.{@link HashMap#put(Object, Object) put}(VRConstants.SETTING_FLIP_EYES, value)</code>
+     */
+    public static final String SETTING_FLIP_EYES = "VRFlipEyes";
+    
+    /**
+     * An AppSettings parameter that set if the GUI has to be displayed even if it is behind objects.
+     * <b>Type: </b><code>boolean</code><br>
+	 * <b>Usage: </b><code>{@link AppSettings appSettings}.{@link HashMap#put(Object, Object) put}(VRConstants.SETTING_GUI_OVERDRAW, value)</code>
+     * 
+     */
+    public static final String SETTING_GUI_OVERDRAW = "VRGUIOverdraw";
+    
+    /**
+     * An AppSettings parameter that set if the GUI surface has to be curved.
+     * <b>Type: </b><code>boolean</code><br>
+	 * <b>Usage: </b><code>{@link AppSettings appSettings}.{@link HashMap#put(Object, Object) put}(VRConstants.SETTING_GUI_CURVED_SURFACE, value)</code>
+     */
+    public static final String SETTING_GUI_CURVED_SURFACE = "VRGUICurvedSurface";
+  
+    /**
+     * An AppSettings parameter that set if a mirror rendering has to be displayed on the screen. 
+     * Runs faster when set to <code>false</code>.
+     * <b>Type: </b><code>boolean</code><br>
+	 * <b>Usage: </b><code>{@link AppSettings appSettings}.{@link HashMap#put(Object, Object) put}(VRConstants.SETTING_ENABLE_MIRROR_WINDOW, value)</code>
+     */
+    public static final String SETTING_ENABLE_MIRROR_WINDOW = "VREnableMirrorWindow";
+    
+    /**
+     * An AppSettings parameter that set if the VR rendering has to be disabled, 
+     * regardless VR API and devices are presents.
+     * <b>Type: </b><code>boolean</code><br>
+	 * <b>Usage: </b><code>{@link AppSettings appSettings}.{@link HashMap#put(Object, Object) put}(VRConstants.SETTING_DISABLE_VR, value)</code>
+     */
+    public static final String SETTING_DISABLE_VR = "VRDisable";
+    
+    
+    /**
+     * An AppSettings parameter that set if the VR user is seated.
+     * <b>Type: </b><code>boolean</code><br>
+	 * <b>Usage: </b><code>{@link AppSettings appSettings}.{@link HashMap#put(Object, Object) put}(VRConstants.SETTING_SEATED_EXPERIENCE, value)</code>
+     */
+    public static final String SETTING_SEATED_EXPERIENCE = "VRSeatedExperience";
+    
+    /**
+     * An AppSettings parameter that set if the GUI has to be ignored.
+     * <b>Type: </b><code>boolean</code><br>
+	 * <b>Usage: </b><code>{@link AppSettings appSettings}.{@link HashMap#put(Object, Object) put}(VRConstants.SETTING_NO_GUI, value)</code>
+     */
+    public static final String SETTING_NO_GUI = "VRNoGUI";
+    
+    /**
+     * An AppSettings parameter that set if instance rendering has to be used. 
+     * This setting requires some vertex shader changes (see Common/MatDefs/VR/Unshaded.j3md).
+     * <b>Type: </b><code>boolean</code><br>
+	 * <b>Usage: </b><code>{@link AppSettings appSettings}.{@link HashMap#put(Object, Object) put}(VRConstants.SETTING_INSTANCE_RENDERING, value)</code>
+     */
+    public static final String SETTING_INSTANCE_RENDERING = "VRInstanceRendering";
+    
+    /**
+     * An AppSettings parameter that set if Multi Sample Anti Aliasing has to be enabled.
+     * <b>Type: </b><code>boolean</code><br>
+	 * <b>Usage: </b><code>{@link AppSettings appSettings}.{@link HashMap#put(Object, Object) put}(VRConstants.SETTING_DISABLE_MSAA, value)</code>
+     */
+    public static final String SETTING_DISABLE_MSAA = "VRDisableMSAA";
+    
+    /**
+     * An AppSettings parameter that set the default field of view (FOV) value.
+     * <b>Type: </b><code>float</code><br>
+	 * <b>Usage: </b><code>{@link AppSettings appSettings}.{@link HashMap#put(Object, Object) put}(VRConstants.SETTING_DEFAULT_FOV, value)</code>
+     */
+    public static final String SETTING_DEFAULT_FOV = "VRDefaultFOV";
+    
+    /**
+     * An AppSettings parameter that set the default aspect ratio.
+     * <b>Type: </b><code>float</code><br>
+	 * <b>Usage: </b><code>{@link AppSettings appSettings}.{@link HashMap#put(Object, Object) put}(VRConstants.SETTING_DEFAULT_ASPECT_RATIO, value)</code>
+     */
+    public static final String SETTING_DEFAULT_ASPECT_RATIO = "VRDefaultAspectRatio";
+    
+    /**
+     * An AppSettings parameter that specifies the underlying VR API. Possible values are:<br>
+     * <ul>
+     * <li>{@link VRConstants#SETTING_VRAPI_OPENVR_VALUE SETTING_VRAPI_OPENVR_VALUE}: Use OpenVR binding.
+     * <li>{@link VRConstants#SETTING_VRAPI_OSVR_VALUE SETTING_VRAPI_OSVR_VALUE}: Use OSVR binding.
+     * <li>{@link VRConstants#SETTING_VRAPI_OPENVR_LWJGL_VALUE SETTING_VRAPI_OPENVR_LWJGL_VALUE}: Use OpenVR binding from LWJGL.
+     * </ul>
+     * <b>Type: </b><code>int</code><br>
+	 * <b>Usage: </b><code>{@link AppSettings appSettings}.{@link HashMap#put(Object, Object) put}(VRConstants.SETTING_VRAPI, value)</code>
+
+     */
+    public static final String SETTING_VRAPI = "VRAPI";
+    
+    /**
+     * The identifier of the OpenVR system.
+     * @see #SETTING_VRAPI
+     */
+    public static final int SETTING_VRAPI_OPENVR_VALUE       = 1;
+    
+    /**
+     * The identifier of the OSVR system.
+     * @see #SETTING_VRAPI
+     */
+    public static final int SETTING_VRAPI_OSVR_VALUE         = 2;
+    
+    /**
+     * The identifier of the OpenVR from LWJGL system.
+     * @see #SETTING_VRAPI
+     */
+    public static final int SETTING_VRAPI_OPENVR_LWJGL_VALUE = 3;
+    
+    
+    
+}

+ 140 - 0
jme3-vr/src/main/java/com/jme3/input/lwjgl/GlfwKeyInputVR.java

@@ -0,0 +1,140 @@
+package com.jme3.input.lwjgl;
+
+/*
+ * Copyright (c) 2009-2012 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import com.jme3.input.KeyInput;
+import com.jme3.input.RawInputListener;
+import com.jme3.input.event.KeyInputEvent;
+import com.jme3.system.lwjgl.LwjglWindowVR;
+
+import org.lwjgl.glfw.GLFWKeyCallback;
+
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.logging.Logger;
+
+import static org.lwjgl.glfw.GLFW.*;
+
+/**
+ * A key input that wraps GLFW underlying components.
+ * @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 GlfwKeyInputVR implements KeyInput {
+
+    private static final Logger logger = Logger.getLogger(GlfwKeyInput.class.getName());
+
+    private LwjglWindowVR context;
+    private RawInputListener listener;
+    private boolean initialized, shift_pressed;
+    private GLFWKeyCallback keyCallback;
+    private Queue<KeyInputEvent> keyInputEvents = new LinkedList<KeyInputEvent>();
+
+    /**
+     * Create a new input attached to the given {@link LwjglWindowVR context}.
+     * @param context the context to attach to this input.
+     */
+    public GlfwKeyInputVR(LwjglWindowVR context) {
+        this.context = context;
+    }
+
+    public void initialize() {
+        if (!context.isRenderable()) {
+            return;
+        }
+
+        glfwSetKeyCallback(context.getWindowHandle(), keyCallback = new GLFWKeyCallback() {
+            @Override
+            public void invoke(long window, int key, int scancode, int action, int mods) {
+                scancode = GlfwKeyMap.toJmeKeyCode(key);
+                if( key == GLFW_KEY_LEFT_SHIFT || key == GLFW_KEY_RIGHT_SHIFT ) {
+                    shift_pressed = (action == GLFW_PRESS);
+                } else if( key >= 'A' && key <= 'Z' && !shift_pressed ) {
+                    key += 32; // make lowercase
+                } else if( key >= 'a' && key <= 'z' && shift_pressed ) {
+                    key -= 32; // make uppercase
+                }
+                final KeyInputEvent evt = new KeyInputEvent(scancode, (char) key, GLFW_PRESS == action, GLFW_REPEAT == action);
+                evt.setTime(getInputTimeNanos());
+                keyInputEvents.add(evt);
+            }
+        });
+
+        glfwSetInputMode(context.getWindowHandle(), GLFW_STICKY_KEYS, 1);
+
+        initialized = true;
+        logger.fine("Keyboard created.");
+    }
+
+    /**
+     * Get the key count.
+     * @return the key count.
+     */
+    public int getKeyCount() {
+        // This might not be correct
+        return GLFW_KEY_LAST - GLFW_KEY_SPACE;
+    }
+
+    public void update() {
+        if (!context.isRenderable()) {
+            return;
+        }
+
+        while (!keyInputEvents.isEmpty()) {
+            listener.onKeyEvent(keyInputEvents.poll());
+        }
+    }
+
+    public void destroy() {
+        if (!context.isRenderable()) {
+            return;
+        }
+
+        keyCallback.free();
+        
+        logger.fine("Keyboard destroyed.");
+    }
+
+    public boolean isInitialized() {
+        return initialized;
+    }
+
+    public void setInputListener(RawInputListener listener) {
+        this.listener = listener;
+    }
+
+    public long getInputTimeNanos() {
+        return (long) (glfwGetTime() * 1000000000);
+    }
+}

+ 329 - 0
jme3-vr/src/main/java/com/jme3/input/lwjgl/GlfwMouseInputVR.java

@@ -0,0 +1,329 @@
+package com.jme3.input.lwjgl;
+
+/*
+ * Copyright (c) 2009-2012 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import com.jme3.cursors.plugins.JmeCursor;
+import com.jme3.input.MouseInput;
+import com.jme3.input.RawInputListener;
+import com.jme3.input.event.MouseButtonEvent;
+import com.jme3.input.event.MouseMotionEvent;
+import com.jme3.system.lwjgl.LwjglWindowVR;
+import com.jme3.util.BufferUtils;
+
+import org.lwjgl.glfw.GLFWCursorPosCallback;
+import org.lwjgl.glfw.GLFWMouseButtonCallback;
+import org.lwjgl.glfw.GLFWScrollCallback;
+
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Queue;
+import java.util.logging.Logger;
+
+import static org.lwjgl.glfw.GLFW.*;
+import org.lwjgl.glfw.GLFWImage;
+import org.lwjgl.system.MemoryUtil;
+
+/**
+ * Captures mouse input using GLFW callbacks. It then temporarily stores these in event queues which are processed in the
+ * {@link #update()} method. Due to some of the GLFW button id's there is a conversion method in this class which will
+ * convert the GLFW left, middle and right mouse button to JME3 left, middle and right button codes.<br><br>
+ * This class support modifications dedicated to VR rendering.
+ * @author Daniel Johansson (dannyjo)
+ * @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 GlfwMouseInputVR implements MouseInput {
+
+    private static final Logger logger = Logger.getLogger(GlfwMouseInputVR.class.getName());
+
+    private static final int WHEEL_SCALE = 120;
+
+    private LwjglWindowVR context;
+    private RawInputListener listener;
+    private boolean cursorVisible = true;
+    private int mouseX, xDelta;
+    private int mouseY, yDelta;
+    private int mouseWheel;
+    private boolean initialized;
+    private GLFWCursorPosCallback cursorPosCallback;
+    private GLFWScrollCallback scrollCallback;
+    private GLFWMouseButtonCallback mouseButtonCallback;
+    private Queue<MouseMotionEvent> mouseMotionEvents = new LinkedList<MouseMotionEvent>();
+    private Queue<MouseButtonEvent> mouseButtonEvents = new LinkedList<MouseButtonEvent>();
+
+    private Map<JmeCursor, Long> jmeToGlfwCursorMap = new HashMap<JmeCursor, Long>();
+
+    /**
+     * Create a new mouse input attached to the given {@link LwjglWindowVR context}.
+     * @param context the context to which to attach the input.
+     */
+    public GlfwMouseInputVR(LwjglWindowVR context) {
+        this.context = context;
+    }
+
+    private void onCursorPos(long window, double xpos, double ypos) {
+                int x = (int) Math.round(xpos);
+                int y = context.getSettings().getHeight() - (int) Math.round(ypos);
+
+                if (mouseX == 0) {
+                    mouseX = x;
+                }
+
+                if (mouseY == 0) {
+                    mouseY = y;
+                }
+
+                xDelta = x - mouseX;
+                yDelta = y - mouseY;
+                mouseX = x;
+                mouseY = y;
+
+                if (xDelta != 0 || yDelta != 0) {
+                    final MouseMotionEvent mouseMotionEvent = new MouseMotionEvent(x, y, xDelta, yDelta, mouseWheel, 0);
+                    mouseMotionEvent.setTime(getInputTimeNanos());
+                    mouseMotionEvents.add(mouseMotionEvent);
+                }
+            }
+
+    private void onWheelScroll(long window, double xOffset, double yOffset) {
+                mouseWheel += yOffset;
+
+                final MouseMotionEvent mouseMotionEvent = new MouseMotionEvent(mouseX, mouseY, 0, 0, mouseWheel, (int) Math.round(yOffset));
+                mouseMotionEvent.setTime(getInputTimeNanos());
+                mouseMotionEvents.add(mouseMotionEvent);
+            }
+    private void onMouseButton(final long window, final int button, final int action, final int mods) {
+        final MouseButtonEvent mouseButtonEvent = new MouseButtonEvent(convertButton(button), action == GLFW_PRESS, mouseX, mouseY);
+        mouseButtonEvent.setTime(getInputTimeNanos());
+        mouseButtonEvents.add(mouseButtonEvent);
+    }
+
+    public void initialize() {
+        glfwSetCursorPosCallback(context.getWindowHandle(), cursorPosCallback = new GLFWCursorPosCallback() {
+            @Override
+            public void invoke(long window, double xpos, double ypos) {
+                onCursorPos(window, xpos, ypos);
+            }
+        });
+
+        glfwSetScrollCallback(context.getWindowHandle(), scrollCallback = new GLFWScrollCallback() {
+            @Override
+            public void invoke(final long window, final double xOffset, final double yOffset) {
+                onWheelScroll(window, xOffset, yOffset * WHEEL_SCALE);
+            }
+        });
+
+        glfwSetMouseButtonCallback(context.getWindowHandle(), mouseButtonCallback = new GLFWMouseButtonCallback() {
+            @Override
+            public void invoke(final long window, final int button, final int action, final int mods) {
+                onMouseButton(window, button, action, mods);
+            }
+        });
+
+        setCursorVisible(cursorVisible);
+        logger.fine("Mouse created.");
+        initialized = true;
+    }
+
+    /**
+     * Set the position of the cursor on the display.
+     * @param x the x position of the cursor (pixel).
+     * @param y the y position of the cursor (pixel).
+     */
+    public void setCursorPosition(int x, int y) {
+        if (!context.isRenderable()) {
+            return;
+        }
+        
+        glfwSetCursorPos(context.getWindowHandle(), x, y);	
+    }
+    
+    /**
+     * Hide the active cursor within the display.
+     */
+    public void hideActiveCursor() {
+        if (!context.isRenderable()) {
+            return;
+        }
+
+        if (cursorVisible) {
+            glfwSetInputMode(context.getWindowHandle(), GLFW_CURSOR, GLFW_CURSOR_HIDDEN);            
+        }
+    }
+    
+    /**
+     * Get the last delta in x (pixel).
+     * @return the last delta in x (pixel).
+     * @see #getLastDeltaY()
+     */
+    public int getLastDeltaX() {
+        return xDelta;
+    }
+    
+    /**
+     * Get the last delta in y (pixel).
+     * @return the last delta in y (pixel).
+     * @see #getLastDeltaX()
+     */
+    public int getLastDeltaY() {
+        return yDelta;
+    }
+    
+    /**
+     * Clear the last x and y deltas.
+     * @see #getLastDeltaX()
+     * @see #getLastDeltaY()
+     */
+    public void clearDeltas() {
+        xDelta = 0;
+        yDelta = 0;
+    }
+    
+    /**
+     * Check if the input is initialized.
+     * @return <code>true</code> if the input is initialized and <code>false</code> otherwise.
+     */
+    public boolean isInitialized() {
+        return initialized;
+    }
+
+    @Override
+    public int getButtonCount() {
+        return GLFW_MOUSE_BUTTON_LAST + 1;
+    }
+
+    @Override
+    public void update() {
+        while (!mouseMotionEvents.isEmpty()) {
+            listener.onMouseMotionEvent(mouseMotionEvents.poll());
+        }
+
+        while (!mouseButtonEvents.isEmpty()) {
+            listener.onMouseButtonEvent(mouseButtonEvents.poll());
+        }
+    }
+
+    @Override
+    public void destroy() {
+        if (!context.isRenderable()) {
+            return;
+        }
+        
+        cursorPosCallback.free();
+        scrollCallback.free();
+        mouseButtonCallback.free();
+        
+        for (long glfwCursor : jmeToGlfwCursorMap.values()) {
+            glfwDestroyCursor(glfwCursor);
+        }
+
+        logger.fine("Mouse destroyed.");
+    }
+
+    @Override
+    public void setCursorVisible(boolean visible) {
+        cursorVisible = visible;
+
+        if (!context.isRenderable()) {
+            return;
+        }
+
+        if (cursorVisible) {
+            glfwSetInputMode(context.getWindowHandle(), GLFW_CURSOR, GLFW_CURSOR_NORMAL);
+        } else {
+            glfwSetInputMode(context.getWindowHandle(), GLFW_CURSOR, GLFW_CURSOR_DISABLED);
+        }
+    }
+
+    @Override
+    public void setInputListener(RawInputListener listener) {
+        this.listener = listener;
+    }
+
+    @Override
+    public long getInputTimeNanos() {
+        return (long) (glfwGetTime() * 1000000000);
+    }
+
+    private long createGlfwCursor(JmeCursor jmeCursor) {
+        GLFWImage glfwImage = new GLFWImage(BufferUtils.createByteBuffer(GLFWImage.SIZEOF));
+
+        // TODO: currently animated cursors are not supported
+        IntBuffer imageData = jmeCursor.getImagesData();
+        ByteBuffer buf = BufferUtils.createByteBuffer(imageData.capacity() * 4);
+        buf.asIntBuffer().put(imageData);
+
+        glfwImage.set(jmeCursor.getWidth(), jmeCursor.getHeight(), buf);
+
+        return glfwCreateCursor(glfwImage, jmeCursor.getXHotSpot(), jmeCursor.getYHotSpot());
+    }
+
+    public void setNativeCursor(JmeCursor jmeCursor) {
+        if (jmeCursor != null) {
+            Long glfwCursor = jmeToGlfwCursorMap.get(jmeCursor);
+
+            if (glfwCursor == null) {
+                glfwCursor = createGlfwCursor(jmeCursor);
+                jmeToGlfwCursorMap.put(jmeCursor, glfwCursor);
+            }
+
+            glfwSetCursor(context.getWindowHandle(), glfwCursor);
+        } else {
+            glfwSetCursor(context.getWindowHandle(), MemoryUtil.NULL);
+        }
+    }
+
+    /**
+     * Simply converts the GLFW button code to a JME button code. If there is no
+     * match it just returns the GLFW button code. Bear in mind GLFW supports 8
+     * different mouse buttons.
+     *
+     * @param glfwButton the raw GLFW button index.
+     * @return the mapped {@link MouseInput} button id.
+     */
+    private int convertButton(final int glfwButton) {
+        switch (glfwButton) {
+            case GLFW_MOUSE_BUTTON_LEFT:
+            return MouseInput.BUTTON_LEFT;
+            case GLFW_MOUSE_BUTTON_MIDDLE:
+            return MouseInput.BUTTON_MIDDLE;
+            case GLFW_MOUSE_BUTTON_RIGHT:
+            return MouseInput.BUTTON_RIGHT;
+            default:
+                return glfwButton;
+        }
+    }
+}

+ 64 - 0
jme3-vr/src/main/java/com/jme3/input/vr/HmdType.java

@@ -0,0 +1,64 @@
+package com.jme3.input.vr;
+
+/**
+ * The type of VR Head Mounted Device (HMD)
+ * @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 enum HmdType {
+	
+	/**
+	 * <a href="https://www.vive.com/fr/">HTC vive</a> Head Mounted Device (HMD).
+	 */
+    HTC_VIVE, 
+    
+    /**
+     * <a href="https://www3.oculus.com/en-us/rift/">Occulus Rift</a> Head Mounted Device (HMD).
+     */
+    OCULUS_RIFT, 
+    
+    /**
+     * <a href="http://www.osvr.org/">OSVR</a> generic Head Mounted Device (HMD).
+     */
+    OSVR, 
+    
+    /**
+     * <a href="https://www.getfove.com/">FOVE</a> Head Mounted Device (HMD).
+     */
+    FOVE, 
+    
+    /**
+     * <a href="http://www.starvr.com/">STARVR</a> Head Mounted Device (HMD).
+     */
+    STARVR, 
+    
+    /**
+     * <a href="http://gamefacelabs.com/">GameFace</a> Head Mounted Device (HMD).
+     */
+    GAMEFACE, 
+    
+    /**
+     * <a href="https://www.playstation.com/en-us/explore/playstation-vr/">PlayStation VR</a> (formely Morpheus) Head Mounted Device (HMD).
+     */
+    MORPHEUS, 
+    
+    /**
+     * <a href="http://www.samsung.com/fr/galaxynote4/gear-vr/">Samsung GearVR</a> Head Mounted Device (HMD).
+     */
+    GEARVR, 
+    
+    /**
+     * a null Head Mounted Device (HMD).
+     */
+    NULL, 
+    
+    /**
+     * a none Head Mounted Device (HMD).
+     */
+    NONE, 
+    
+    /**
+     * a not referenced Head Mounted Device (HMD).
+     */
+    OTHER
+}

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

@@ -0,0 +1,470 @@
+/*
+
+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.VRAppState;
+import com.jme3.app.VRApplication;
+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.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;
+
+import osvrclientkit.OsvrClientKitLibrary;
+import osvrdisplay.OsvrDisplayLibrary;
+import osvrdisplay.OsvrDisplayLibrary.OSVR_DisplayConfig;
+import osvrmatrixconventions.OSVR_Pose3;
+
+import osvrrendermanageropengl.OSVR_OpenResultsOpenGL;
+import osvrrendermanageropengl.OSVR_RenderBufferOpenGL;
+import osvrrendermanageropengl.OSVR_RenderInfoOpenGL;
+import osvrrendermanageropengl.OSVR_RenderParams;
+import osvrrendermanageropengl.OSVR_ViewportDescription;
+import osvrrendermanageropengl.OsvrRenderManagerOpenGLLibrary;
+
+/**
+ * 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;
+    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 VRAppState app = null;
+    
+    /**
+     * Create a new <a href="http://www.osvr.org/">OSVR</a> system attached to the given {@link VRAppState app state}.
+     * @param app the app state to which the input is attached.
+     */
+    public OSVR(VRAppState app){
+    	this.app = app;
+    }
+    
+    /**
+     * 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(app);
+        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 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);
+            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);
+            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;
+    }
+
+	@Override
+	public VRAppState getVRAppState() {
+		return app;
+	}
+
+}

+ 365 - 0
jme3-vr/src/main/java/com/jme3/input/vr/OSVRInput.java

@@ -0,0 +1,365 @@
+/*
+ * 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 java.util.logging.Logger;
+
+import com.jme3.app.VRAppState;
+import com.jme3.app.VRApplication;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Vector2f;
+import com.jme3.math.Vector3f;
+import com.jme3.renderer.Camera;
+import com.jme3.scene.Spatial;
+import com.sun.jna.Callback;
+import com.sun.jna.Pointer;
+import com.sun.jna.ptr.PointerByReference;
+
+import jmevr.util.VRViewManager;
+
+import osvrclientkit.OsvrClientKitLibrary;
+import osvrclientkit.OsvrClientKitLibrary.OSVR_ClientInterface;
+import osvrclientreporttypes.OSVR_AnalogReport;
+import osvrclientreporttypes.OSVR_ButtonReport;
+import osvrclientreporttypes.OSVR_Pose3;
+import osvrinterface.OsvrInterfaceLibrary;
+import osvrtimevalue.OSVR_TimeValue;
+
+/**
+ * A class that wraps an <a href="http://www.osvr.org/">OSVR</a> input. 
+ * @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 OSVRInput implements VRInputAPI {
+
+	private static final Logger logger = Logger.getLogger(OSVRInput.class.getName());
+	
+    // position example: https://github.com/OSVR/OSVR-Core/blob/master/examples/clients/TrackerState.c
+    // button example: https://github.com/OSVR/OSVR-Core/blob/master/examples/clients/ButtonCallback.c
+    // analog example: https://github.com/OSVR/OSVR-Core/blob/master/examples/clients/AnalogCallback.c
+    
+    private static final int ANALOG_COUNT = 3, BUTTON_COUNT = 7, CHANNEL_COUNT = 3;
+    
+    OSVR_ClientInterface[][] buttons;
+    OSVR_ClientInterface[][][] analogs;
+    OSVR_ClientInterface[] hands;
+    
+    OSVR_Pose3[] handState;
+    Callback buttonHandler, analogHandler;
+    OSVR_TimeValue tv = new OSVR_TimeValue();
+    boolean[] isHandTracked = new boolean[2];
+    
+    private float[][][] analogState;
+    private float[][] buttonState;
+    
+    private final Quaternion tempq = new Quaternion();
+    private final Vector3f tempv = new Vector3f();
+    private final Vector2f temp2 = new Vector2f();
+    private final boolean[][] buttonDown = new boolean[16][16];
+    
+    private static final Vector2f temp2Axis = new Vector2f();
+    private static final Vector2f lastCallAxis[] = new Vector2f[16];
+    private static float axisMultiplier = 1f;
+    
+    private VRAppState app = null;
+    
+    /**
+     * Get the system String that identifies a controller.
+     * @param left is the controller is the left one (<code>false</code> if the right controller is needed).
+     * @param index the index of the controller.
+     * @return the system String that identifies the controller.
+     */
+    public static byte[] getButtonString(boolean left, byte index) {
+        if( left ) {
+            return new byte[] { '/', 'c', 'o', 'n', 't', 'r', 'o', 'l', 'l', 'e', 'r', '/', 'l', 'e', 'f', 't', '/', index, (byte)0 };
+        }
+        return new byte[] { '/', 'c', 'o', 'n', 't', 'r', 'o', 'l', 'l', 'e', 'r', '/', 'r', 'i', 'g', 'h', 't', '/', index, (byte)0 };
+    }
+    
+    /**
+     * The left hand system String.
+     */
+    public static byte[] leftHand = { '/', 'm', 'e', '/', 'h', 'a', 'n', 'd', 's', '/', 'l', 'e', 'f', 't', (byte)0 };
+    
+    /**
+     * The right hand system String.
+     */
+    public static byte[] rightHand = { '/', 'm', 'e', '/', 'h', 'a', 'n', 'd', 's', '/', 'r', 'i', 'g', 'h', 't', (byte)0 };
+
+    
+    /**
+     * Create a new <a href="http://www.osvr.org/">OSVR</a> input attached to the given {@link VRAppState app state}.
+     * @param app the app state to which the input is attached.
+     */
+    public OSVRInput(VRAppState app){
+      this.app = app;
+    }
+    
+    
+    @Override
+    public boolean isButtonDown(int controllerIndex, VRInputType checkButton) {
+        return buttonState[controllerIndex][checkButton.getValue()] != 0f;
+    }
+
+    @Override
+    public boolean wasButtonPressedSinceLastCall(int controllerIndex, VRInputType checkButton) {
+        boolean buttonDownNow = isButtonDown(controllerIndex, checkButton);
+        int checkButtonValue = checkButton.getValue();
+        boolean retval = buttonDownNow == true && buttonDown[controllerIndex][checkButtonValue] == false;
+        buttonDown[controllerIndex][checkButtonValue] = buttonDownNow;
+        return retval;
+    }
+
+    @Override
+    public void resetInputSinceLastCall() {
+        for(int i=0;i<lastCallAxis.length;i++) {
+            lastCallAxis[i].x = 0f;
+            lastCallAxis[i].y = 0f;
+        }
+        for(int i=0;i<16;i++) {
+            for(int j=0;j<16;j++) {
+                buttonDown[i][j] = false;
+            }
+        }
+    }
+    
+    @Override
+    public Vector2f getAxisDeltaSinceLastCall(int controllerIndex, VRInputType forAxis) {                
+        int axisIndex = forAxis.getValue();
+        temp2Axis.set(lastCallAxis[axisIndex]);
+        lastCallAxis[axisIndex].set(getAxis(controllerIndex, forAxis));
+        if( (temp2Axis.x != 0f || temp2Axis.y != 0f) && (lastCallAxis[axisIndex].x != 0f || lastCallAxis[axisIndex].y != 0f) ) {
+            temp2Axis.subtractLocal(lastCallAxis[axisIndex]);        
+        } else {
+            // move made from rest, don't count as a delta move
+            temp2Axis.x = 0f;
+            temp2Axis.y = 0f;
+        }
+        return temp2Axis;
+    }
+
+    @Override
+    public Vector3f getVelocity(int controllerIndex) {
+        return Vector3f.ZERO;
+    }
+
+    @Override
+    public Vector3f getAngularVelocity(int controllerIndex) {
+        return Vector3f.ZERO;
+    }
+
+    @Override
+    public Vector2f getAxisRaw(int controllerIndex, VRInputType forAxis) {
+        temp2.x = analogState[controllerIndex][forAxis.getValue()][0];
+        temp2.y = analogState[controllerIndex][forAxis.getValue()][1];
+        return temp2;
+    }
+
+    @Override
+    public Vector2f getAxis(int controllerIndex, VRInputType forAxis) {
+        temp2.x = analogState[controllerIndex][forAxis.getValue()][0] * axisMultiplier;
+        temp2.y = analogState[controllerIndex][forAxis.getValue()][1] * axisMultiplier;
+        return temp2;
+    }
+    
+    private OSVR_ClientInterface getInterface(byte[] str) {
+        PointerByReference pbr = new PointerByReference();
+        OsvrClientKitLibrary.osvrClientGetInterface((OsvrClientKitLibrary.OSVR_ClientContext)app.getVRHardware().getVRSystem(), str, pbr);
+        return new OSVR_ClientInterface(pbr.getValue());
+    }
+
+    @Override
+    public boolean init() {
+        
+    	logger.config("Initialize OSVR input.");
+    	
+        buttonHandler = new Callback() {
+            @SuppressWarnings("unused")
+			public void invoke(Pointer userdata, Pointer timeval, OSVR_ButtonReport report) {
+                for(int i=0;i<2;i++) {
+                    for(int j=0;j<BUTTON_COUNT;j++) {
+                        if( buttons[i][j] == null ) continue;
+                        if( userdata.toString().equals(buttons[i][j].getPointer().toString()) ) {
+                            buttonState[i][j] = report.state;
+                            return;
+                        }
+                    }
+                }
+            }                
+        };  
+        analogHandler = new Callback() {
+            @SuppressWarnings("unused")
+			public void invoke(Pointer userdata, Pointer timeval, OSVR_AnalogReport report) {
+                for(int i=0;i<2;i++) {
+                    for(int j=0;j<ANALOG_COUNT;j++) {
+                        for(int k=0;k<CHANNEL_COUNT;k++) {
+                            if( analogs[i][j][k] == null ) continue;
+                            if( userdata.toString().equals(analogs[i][j][k].getPointer().toString()) ) {
+                                analogState[i][j][k] = (float)report.state;
+                                return;
+                            }
+                        }
+                    }
+                }
+            }                
+        };  
+        
+        buttons = new OSVR_ClientInterface[2][BUTTON_COUNT];
+        analogs = new OSVR_ClientInterface[2][ANALOG_COUNT][CHANNEL_COUNT];
+        buttonState = new float[2][BUTTON_COUNT];
+        analogState = new float[2][ANALOG_COUNT][CHANNEL_COUNT];
+        hands = new OSVR_ClientInterface[2];
+        hands[0] = getInterface(leftHand);
+        hands[1] = getInterface(rightHand);
+        handState = new OSVR_Pose3[2];
+        handState[0] = new OSVR_Pose3(); handState[1] = new OSVR_Pose3();
+        for(int h=0;h<2;h++) {
+            for(int i=0;i<BUTTON_COUNT-2;i++) {
+                buttons[h][i] = getInterface(getButtonString(h==0, (byte)Integer.toString(i).toCharArray()[0]));
+                OsvrClientKitLibrary.osvrRegisterButtonCallback(buttons[h][i], buttonHandler, buttons[h][i].getPointer()); 
+            }
+        }
+        buttons[0][BUTTON_COUNT-2] = getInterface(new byte[] { '/', 'c', 'o', 'n', 't', 'r', 'o', 'l', 'l', 'e', 'r', '/', 'l', 'e', 'f', 't', '/', 'b', 'u', 'm', 'p', 'e', 'r', (byte)0 } );
+        OsvrClientKitLibrary.osvrRegisterButtonCallback(buttons[0][BUTTON_COUNT-2], buttonHandler, buttons[0][BUTTON_COUNT-2].getPointer()); 
+        buttons[1][BUTTON_COUNT-2] = getInterface(new byte[] { '/', 'c', 'o', 'n', 't', 'r', 'o', 'l', 'l', 'e', 'r', '/', 'r', 'i', 'g', 'h', 't', '/', 'b', 'u', 'm', 'p', 'e', 'r', (byte)0 } );
+        OsvrClientKitLibrary.osvrRegisterButtonCallback(buttons[1][BUTTON_COUNT-2], buttonHandler, buttons[1][BUTTON_COUNT-2].getPointer()); 
+        buttons[0][BUTTON_COUNT-1] = getInterface(new byte[] { '/', 'c', 'o', 'n', 't', 'r', 'o', 'l', 'l', 'e', 'r', '/', 'l', 'e', 'f', 't', '/', 'j', 'o', 'y', 's', 't', 'i', 'c', 'k', '/', 'b', 'u', 't', 't', 'o', 'n', (byte)0 } );
+        OsvrClientKitLibrary.osvrRegisterButtonCallback(buttons[0][BUTTON_COUNT-1], buttonHandler, buttons[0][BUTTON_COUNT-1].getPointer()); 
+        buttons[1][BUTTON_COUNT-1] = getInterface(new byte[] { '/', 'c', 'o', 'n', 't', 'r', 'o', 'l', 'l', 'e', 'r', '/', 'r', 'i', 'g', 'h', 't', '/', 'j', 'o', 'y', 's', 't', 'i', 'c', 'k', '/', 'b', 'u', 't', 't', 'o', 'n', (byte)0 } );
+        OsvrClientKitLibrary.osvrRegisterButtonCallback(buttons[1][BUTTON_COUNT-1], buttonHandler, buttons[1][BUTTON_COUNT-1].getPointer()); 
+            
+        analogs[0][0][0] = getInterface(new byte[] { '/', 'c', 'o', 'n', 't', 'r', 'o', 'l', 'l', 'e', 'r', '/', 'l', 'e', 'f', 't', '/', 't', 'r', 'i', 'g', 'g', 'e', 'r', (byte)0 } );
+        analogs[1][0][0] = getInterface(new byte[] { '/', 'c', 'o', 'n', 't', 'r', 'o', 'l', 'l', 'e', 'r', '/', 'r', 'i', 'g', 'h', 't', '/', 't', 'r', 'i', 'g', 'g', 'e', 'r', (byte)0 } );
+        OsvrClientKitLibrary.osvrRegisterAnalogCallback(analogs[0][0][0], analogHandler, analogs[0][0][0].getPointer());
+        OsvrClientKitLibrary.osvrRegisterAnalogCallback(analogs[1][0][0], analogHandler, analogs[1][0][0].getPointer());
+        analogs[0][1][0] = getInterface(new byte[] { '/', 'c', 'o', 'n', 't', 'r', 'o', 'l', 'l', 'e', 'r', '/', 'l', 'e', 'f', 't', '/', 'j', 'o', 'y', 's', 't', 'i', 'c', 'k', '/', 'x', (byte)0 } );
+        analogs[0][1][1] = getInterface(new byte[] { '/', 'c', 'o', 'n', 't', 'r', 'o', 'l', 'l', 'e', 'r', '/', 'l', 'e', 'f', 't', '/', 'j', 'o', 'y', 's', 't', 'i', 'c', 'k', '/', 'y', (byte)0 } );
+        OsvrClientKitLibrary.osvrRegisterAnalogCallback(analogs[0][1][0], analogHandler, analogs[0][1][0].getPointer());
+        OsvrClientKitLibrary.osvrRegisterAnalogCallback(analogs[0][1][1], analogHandler, analogs[0][1][1].getPointer());
+        analogs[1][1][0] = getInterface(new byte[] { '/', 'c', 'o', 'n', 't', 'r', 'o', 'l', 'l', 'e', 'r', '/', 'r', 'i', 'g', 'h', 't', '/', 'j', 'o', 'y', 's', 't', 'i', 'c', 'k', '/', 'x', (byte)0 } );
+        analogs[1][1][1] = getInterface(new byte[] { '/', 'c', 'o', 'n', 't', 'r', 'o', 'l', 'l', 'e', 'r', '/', 'r', 'i', 'g', 'h', 't', '/', 'j', 'o', 'y', 's', 't', 'i', 'c', 'k', '/', 'y', (byte)0 } );
+        OsvrClientKitLibrary.osvrRegisterAnalogCallback(analogs[1][1][0], analogHandler, analogs[1][1][0].getPointer());
+        OsvrClientKitLibrary.osvrRegisterAnalogCallback(analogs[1][1][1], analogHandler, analogs[1][1][1].getPointer());
+        
+        return true;
+    }
+
+    @Override
+    public int getTrackedControllerCount() {
+        return (isHandTracked[0]?1:0) + (isHandTracked[1]?1:0);
+    }
+
+    @Override
+    public void updateConnectedControllers() {
+        
+    }
+
+    @Override
+    public void updateControllerStates() {
+        for(int i=0;i<hands.length;i++) {
+            isHandTracked[i] = OsvrInterfaceLibrary.osvrGetPoseState(hands[i], tv, handState[i]) == 0;
+        }
+    }
+
+    @Override
+    public Object getRawControllerState(int index) {
+        return handState[index];
+    }
+
+    //@Override
+    //public Matrix4f getPoseForInputDevice(int index) {
+    //    return handState[i].
+    //}
+
+    @Override
+    public boolean isInputFocused() {
+        return true;
+    }
+
+    @Override
+    public boolean isInputDeviceTracking(int index) {
+        return isHandTracked[index];
+    }
+
+    @Override
+    public Quaternion getOrientation(int index) {
+        tempq.set((float)-handState[index].rotation.data[1],
+                  (float)handState[index].rotation.data[2],
+                  (float)-handState[index].rotation.data[3],
+                  (float)handState[index].rotation.data[0]);
+        return tempq;
+    }
+
+    @Override
+    public Vector3f getPosition(int index) {
+        tempv.x = (float)-handState[index].translation.data[0];
+        tempv.y = (float) handState[index].translation.data[1];
+        tempv.z = (float)-handState[index].translation.data[2];
+        return tempv;
+    }
+
+    @Override
+    public Quaternion getFinalObserverRotation(int index) {
+        VRViewManager vrvm = app.getVRViewManager();
+        if( vrvm == null || isInputDeviceTracking(index) == false ) return null;
+        Object obs = app.getObserver();
+        if( obs instanceof Camera ) {
+            tempq.set(((Camera)obs).getRotation());
+        } else {
+            tempq.set(((Spatial)obs).getWorldRotation());
+        }
+        return tempq.multLocal(getOrientation(index));
+    }
+    
+    @Override
+    public Vector3f getFinalObserverPosition(int index) {
+        VRViewManager vrvm = app.getVRViewManager();
+        if( vrvm == null || isInputDeviceTracking(index) == false ) return null;
+        Object obs = app.getObserver();
+        Vector3f pos = getPosition(index);
+        if( obs instanceof Camera ) {
+            ((Camera)obs).getRotation().mult(pos, pos);
+            return pos.addLocal(((Camera)obs).getLocation());
+        } else {
+            ((Spatial)obs).getWorldRotation().mult(pos, pos);
+            return pos.addLocal(((Spatial)obs).getWorldTranslation());
+        }
+    } 
+
+    @Override
+    public void triggerHapticPulse(int controllerIndex, float seconds) {
+        
+    }
+
+    @Override
+    public void swapHands() {
+        // not supported yet
+    }
+
+    @Override
+    public float getAxisMultiplier() {
+        return axisMultiplier;
+    }
+    
+    @Override
+    public void setAxisMultiplier(float set) {
+        axisMultiplier = set;
+    }
+
+
+	@Override
+	public VRAppState getVRAppState() {
+		return app;
+	}
+
+
+	@Override
+	public VRTrackedController getTrackedController(int index) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+    
+}

+ 533 - 0
jme3-vr/src/main/java/com/jme3/input/vr/OpenVR.java

@@ -0,0 +1,533 @@
+/*
+ * 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.VRAppState;
+import com.jme3.app.VRApplication;
+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.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.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.LongBuffer;
+import java.util.Locale;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import jmevr.util.VRUtil;
+
+/**
+ * A class that wraps an <a href="https://github.com/ValveSoftware/openvr/wiki/API-Documentation">OpenVR</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 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 VRAppState app = null;
+    
+    /**
+     * Create a new <a href="https://github.com/ValveSoftware/openvr/wiki/API-Documentation">OpenVR</a> system 
+     * attached to the given {@link VRAppState VR app state}.
+     * @param appState the VR app state to which the api is attached.
+     */
+    public OpenVR(VRAppState appState){
+      this.app = appState;
+    }
+    
+    @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<poseMatrices.length;i++) poseMatrices[i] = new Matrix4f();
+
+            timePerFrame = 1.0 / hmdDisplayFrequency.get(0);
+            
+            // disable all this stuff which kills performance
+            hmdTrackedDevicePoseReference.setAutoRead(false);
+            hmdTrackedDevicePoseReference.setAutoWrite(false);
+            hmdTrackedDevicePoseReference.setAutoSynch(false);
+            for(int i=0;i<JOpenVRLibrary.k_unMaxTrackedDeviceCount;i++) {
+                hmdTrackedDevicePoses[i].setAutoRead(false);
+                hmdTrackedDevicePoses[i].setAutoWrite(false);
+                hmdTrackedDevicePoses[i].setAutoSynch(false);
+            }
+            
+            // init controllers for the first time
+            VRinput = new OpenVRInput(app);
+            VRinput.init();
+            VRinput.updateConnectedControllers();
+            
+            // init bounds & chaperone info
+            VRBounds.init();
+            
+            logger.config("Initializing OpenVR system [SUCCESS]");
+            initSuccess = true;
+            return true;
+        }
+    }
+    
+    @Override
+    public boolean initVRCompositor(boolean allowed) {
+        hmdErrorStore.setValue(0); // clear the error store
+        if( allowed && vrsystemFunctions != null ) {
+        	
+        	IntByReference intptr = JOpenVRLibrary.VR_GetGenericInterface(JOpenVRLibrary.IVRCompositor_Version, hmdErrorStore);
+        	if (intptr != null){
+        	
+        		if (intptr.getPointer() != null){
+            		compositorFunctions = new VR_IVRCompositor_FnTable(intptr.getPointer());
+                    if(compositorFunctions != null && hmdErrorStore.getValue() == 0 ){          
+                        compositorFunctions.setAutoSynch(false);
+                        compositorFunctions.read();
+                        if( app.isSeatedExperience() ) {                    
+                            compositorFunctions.SetTrackingSpace.apply(JOpenVRLibrary.ETrackingUniverseOrigin.ETrackingUniverseOrigin_TrackingUniverseSeated);
+                        } else {
+                            compositorFunctions.SetTrackingSpace.apply(JOpenVRLibrary.ETrackingUniverseOrigin.ETrackingUniverseOrigin_TrackingUniverseStanding);                
+                        }
+                        logger.config("OpenVR Compositor initialized");
+                    } else {
+                        logger.severe("OpenVR Compositor error: " + hmdErrorStore.getValue());
+                        compositorFunctions = null;
+                    }
+        		} else {
+        			logger.log(Level.SEVERE, "Cannot get valid pointer for generic interface \""+JOpenVRLibrary.IVRCompositor_Version+"\", "+OpenVRUtil.getEVRInitErrorString(hmdErrorStore.getValue())+" ("+hmdErrorStore.getValue()+")");
+        			compositorFunctions = null;
+        		}
+
+        	} else {
+        		logger.log(Level.SEVERE, "Cannot get generic interface for \""+JOpenVRLibrary.IVRCompositor_Version+"\", "+OpenVRUtil.getEVRInitErrorString(hmdErrorStore.getValue())+" ("+hmdErrorStore.getValue()+")");
+        		compositorFunctions = null;
+        	}
+        	
+            
+        }
+        if( compositorFunctions == null ) {
+            logger.severe("Skipping VR Compositor...");
+            if( vrsystemFunctions != null ) {
+                vsyncToPhotons = vrsystemFunctions.GetFloatTrackedDeviceProperty.apply(JOpenVRLibrary.k_unTrackedDeviceIndex_Hmd, JOpenVRLibrary.ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_SecondsFromVsyncToPhotons_Float, hmdErrorStore);
+            } else {
+                vsyncToPhotons = 0f;
+            }
+        }
+        return compositorFunctions != null;
+    }
+
+    @Override
+    public void destroy() {
+        JOpenVRLibrary.VR_ShutdownInternal();
+    }
+
+    @Override
+    public boolean isInitialized() {
+        return initSuccess;
+    }
+
+    @Override
+    public void reset() {
+        if( vrsystemFunctions == null ) return;
+        vrsystemFunctions.ResetSeatedZeroPose.apply();
+        hmdSeatToStand = null;
+    }
+
+    @Override
+    public void getRenderSize(Vector2f store) {
+        if( vrsystemFunctions == null ) {
+            // 1344x1512
+            store.x = 1344f;
+            store.y = 1512f;
+        } else {
+            IntByReference x = new IntByReference();
+            IntByReference y = new IntByReference();
+            vrsystemFunctions.GetRecommendedRenderTargetSize.apply(x, y);
+            store.x = x.getValue();
+            store.y = y.getValue();
+        }
+    }
+    /*
+    @Override
+    public float getFOV(int dir) {
+        float val = 0f;
+        if( vrsystemFunctions != null ) {      
+            val = vrsystemFunctions.GetFloatTrackedDeviceProperty.apply(JOpenVRLibrary.k_unTrackedDeviceIndex_Hmd, dir, hmdErrorStore);
+        }
+        // verification of number
+        if( val == 0f ) {
+            return 55f;
+        } else if( val <= 10f ) {
+            // most likely a radian number
+            return val * 57.2957795f;
+        }
+        return val;
+    }
+    */
+    
+    @Override
+    public float getInterpupillaryDistance() {
+        if( vrsystemFunctions == null ) return 0.065f;
+        return vrsystemFunctions.GetFloatTrackedDeviceProperty.apply(JOpenVRLibrary.k_unTrackedDeviceIndex_Hmd, JOpenVRLibrary.ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_UserIpdMeters_Float, hmdErrorStore);
+    }
+    
+    @Override
+    public Quaternion getOrientation() {
+        VRUtil.convertMatrix4toQuat(hmdPose, rotStore);
+        return rotStore;
+    }
+
+    @Override
+    public Vector3f getPosition() {
+        // the hmdPose comes in rotated funny, fix that here
+        hmdPose.toTranslationVector(posStore);
+        posStore.x = -posStore.x;
+        posStore.z = -posStore.z;
+        return posStore;
+    }
+    
+    @Override
+    public void getPositionAndOrientation(Vector3f storePos, Quaternion storeRot) {
+        hmdPose.toTranslationVector(storePos);
+        storePos.x = -storePos.x;
+        storePos.z = -storePos.z;
+        storeRot.set(getOrientation());
+    }    
+    
+    @Override
+    public void updatePose(){
+        if(vrsystemFunctions == null) return;
+        if(compositorFunctions != null) {
+           compositorFunctions.WaitGetPoses.apply(hmdTrackedDevicePoseReference, JOpenVRLibrary.k_unMaxTrackedDeviceCount, null, 0);
+        } else {
+            // wait
+            if( latencyWaitTime > 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(
+                    app.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
+        app.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( app.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);
+        }
+    }
+
+	@Override
+	public VRAppState getVRAppState() {
+		return app;
+	}
+    
+}

+ 410 - 0
jme3-vr/src/main/java/com/jme3/input/vr/OpenVRInput.java

@@ -0,0 +1,410 @@
+/*
+ * 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 java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.jme3.app.VRAppState;
+import com.jme3.app.VRApplication;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Vector2f;
+import com.jme3.math.Vector3f;
+import com.jme3.renderer.Camera;
+import com.jme3.scene.Spatial;
+import com.jme3.system.jopenvr.JOpenVRLibrary;
+import com.jme3.system.jopenvr.OpenVRUtil;
+import com.jme3.system.jopenvr.VRControllerState_t;
+import com.jme3.system.jopenvr.VR_IVRSystem_FnTable;
+
+import jmevr.util.VRUtil;
+import jmevr.util.VRViewManager;
+
+/*
+make helper functions to pull the following easily from raw data (DONE)
+
+trigger:
+Controller#1, Axis#0 X: 0.0, Y: 0.0
+Controller#1, Axis#1 X: 1.0, Y: 0.0
+Controller#1, Axis#2 X: 0.0, Y: 0.0
+Controller#1, Axis#3 X: 0.0, Y: 0.0
+Controller#1, Axis#4 X: 0.0, Y: 0.0
+Button press: 8589934592 (when full), touch: 8589934592
+
+touchpad (upper left):
+Controller#1, Axis#0 X: -0.6059755, Y: 0.2301706
+Controller#1, Axis#1 X: 0.0, Y: 0.0
+Controller#1, Axis#2 X: 0.0, Y: 0.0
+Controller#1, Axis#3 X: 0.0, Y: 0.0
+Controller#1, Axis#4 X: 0.0, Y: 0.0
+Button press: 4294967296 (when pressed in), touch: 4294967296
+
+grip:
+Controller#1, Axis#0 X: 0.0, Y: 0.0
+Controller#1, Axis#1 X: 0.0, Y: 0.0
+Controller#1, Axis#2 X: 0.0, Y: 0.0
+Controller#1, Axis#3 X: 0.0, Y: 0.0
+Controller#1, Axis#4 X: 0.0, Y: 0.0
+Button press: 4, touch: 4
+
+thumb:
+Controller#1, Axis#0 X: 0.0, Y: 0.0
+Controller#1, Axis#1 X: 0.0, Y: 0.0
+Controller#1, Axis#2 X: 0.0, Y: 0.0
+Controller#1, Axis#3 X: 0.0, Y: 0.0
+Controller#1, Axis#4 X: 0.0, Y: 0.0
+Button press: 2, touch: 2
+
+*/
+
+/**
+ * A class that wraps an <a href="https://github.com/ValveSoftware/openvr/wiki/API-Documentation">OpenVR</a> input.<br>
+ * <code>null</code> values will be returned if no valid pose exists, or that input device isn't available
+ * user code should check for <code>null</code> values.
+ * @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 OpenVRInput implements VRInputAPI {
+        
+	private static final Logger logger = Logger.getLogger(OpenVRInput.class.getName());
+	
+    private final VRControllerState_t[] cStates = new VRControllerState_t[JOpenVRLibrary.k_unMaxTrackedDeviceCount];
+    
+    private final Quaternion[] rotStore = new Quaternion[JOpenVRLibrary.k_unMaxTrackedDeviceCount];
+    
+    private final Vector3f[] posStore   = new Vector3f[JOpenVRLibrary.k_unMaxTrackedDeviceCount];
+    
+    private static final int[] controllerIndex = new int[JOpenVRLibrary.k_unMaxTrackedDeviceCount];
+    
+    private int controllerCount = 0;
+    
+    private final Vector2f tempAxis = new Vector2f(), temp2Axis = new Vector2f();
+    
+    private final Vector2f lastCallAxis[] = new Vector2f[JOpenVRLibrary.k_unMaxTrackedDeviceCount];
+    
+    private final boolean needsNewVelocity[]    = new boolean[JOpenVRLibrary.k_unMaxTrackedDeviceCount];
+    
+    private final boolean needsNewAngVelocity[] = new boolean[JOpenVRLibrary.k_unMaxTrackedDeviceCount];
+    
+    private final boolean buttonDown[][]        = new boolean[JOpenVRLibrary.k_unMaxTrackedDeviceCount][16];
+    
+    private float axisMultiplier = 1f;
+    
+    private final Vector3f tempVel = new Vector3f();
+    
+    private final Quaternion tempq = new Quaternion();
+
+    private VRAppState app;
+
+    private List<VRTrackedController> trackedControllers = null;
+    
+    /**
+     * Create a new <a href="https://github.com/ValveSoftware/openvr/wiki/API-Documentation">OpenVR</a> input attached to the given application.
+     * @param application the application to which the input is attached.
+     */
+    public OpenVRInput(VRAppState appState){
+      this.app = appState;
+    }
+    
+    @Override
+    public float getAxisMultiplier() {
+        return axisMultiplier;
+    }
+    
+    @Override
+    public void setAxisMultiplier(float set) {
+        axisMultiplier = set;
+    }
+    
+    @Override
+    public void swapHands() {
+        if( controllerCount != 2 ) return; 
+        int temp = controllerIndex[0];
+        controllerIndex[0] = controllerIndex[1];
+        controllerIndex[1] = temp;
+    }
+    
+    @Override
+    public boolean isButtonDown(int controllerIndex, VRInputType checkButton) {
+        VRControllerState_t cs = cStates[OpenVRInput.controllerIndex[controllerIndex]];
+        switch( checkButton ) {
+            default:
+                return false;
+            case ViveGripButton:
+                return (cs.ulButtonPressed & 4) != 0;
+            case ViveMenuButton:
+                return (cs.ulButtonPressed & 2) != 0;                
+            case ViveTrackpadAxis:
+                return (cs.ulButtonPressed & 4294967296l) != 0;
+            case ViveTriggerAxis:
+                return (cs.ulButtonPressed & 8589934592l) != 0;                
+        }
+    }
+    
+    @Override
+    public boolean wasButtonPressedSinceLastCall(int controllerIndex, VRInputType checkButton) {
+        boolean buttonDownNow = isButtonDown(controllerIndex, checkButton);
+        int checkButtonValue = checkButton.getValue();
+        int cIndex = OpenVRInput.controllerIndex[controllerIndex];
+        boolean retval = buttonDownNow == true && buttonDown[cIndex][checkButtonValue] == false;
+        buttonDown[cIndex][checkButtonValue] = buttonDownNow;
+        return retval;
+    }
+    
+    @Override
+    public void resetInputSinceLastCall() {
+        for(int i=0;i<lastCallAxis.length;i++) {
+            lastCallAxis[i].x = 0f;
+            lastCallAxis[i].y = 0f;
+        }
+        for(int i=0;i<JOpenVRLibrary.k_unMaxTrackedDeviceCount;i++) {
+            for(int j=0;j<16;j++) {
+                buttonDown[i][j] = false;
+            }
+        }
+    }
+    
+    @Override
+    public Vector2f getAxisDeltaSinceLastCall(int controllerIndex, VRInputType forAxis) {                
+        int axisIndex = forAxis.getValue();
+        temp2Axis.set(lastCallAxis[axisIndex]);
+        lastCallAxis[axisIndex].set(getAxis(controllerIndex, forAxis));
+        if( (temp2Axis.x != 0f || temp2Axis.y != 0f) && (lastCallAxis[axisIndex].x != 0f || lastCallAxis[axisIndex].y != 0f) ) {
+            temp2Axis.subtractLocal(lastCallAxis[axisIndex]);        
+        } else {
+            // move made from rest, don't count as a delta move
+            temp2Axis.x = 0f;
+            temp2Axis.y = 0f;
+        }
+        return temp2Axis;
+    }
+    
+    @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;
+    }
+    
+    @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;
+    }
+    
+    @Override
+    public Vector2f getAxisRaw(int controllerIndex, VRInputType forAxis) {
+        VRControllerState_t cs = cStates[OpenVRInput.controllerIndex[controllerIndex]];
+        switch( forAxis ) {
+            default:
+                return null;
+            case ViveTriggerAxis:
+                tempAxis.x = cs.rAxis[1].x;
+                tempAxis.y = tempAxis.x;
+                break;
+            case ViveTrackpadAxis:
+                tempAxis.x = cs.rAxis[0].x;
+                tempAxis.y = cs.rAxis[0].y;
+                break;
+        }       
+        return tempAxis;
+    }
+
+    @Override
+    public Vector2f getAxis(int controllerIndex, VRInputType forAxis) {
+        VRControllerState_t cs = cStates[OpenVRInput.controllerIndex[controllerIndex]];
+        switch( forAxis ) {
+            default:
+                return null;
+            case ViveTriggerAxis:
+                tempAxis.x = cs.rAxis[1].x;
+                tempAxis.y = tempAxis.x;
+                break;
+            case ViveTrackpadAxis:
+                tempAxis.x = cs.rAxis[0].x;
+                tempAxis.y = cs.rAxis[0].y;
+                break;
+        }       
+        tempAxis.x *= axisMultiplier;
+        tempAxis.y *= axisMultiplier;
+        return tempAxis;
+    }
+    
+    @Override
+    public boolean init() {
+    	
+    	logger.config("Initialize OpenVR input.");
+    	
+        for(int i=0;i<JOpenVRLibrary.k_unMaxTrackedDeviceCount;i++) {
+            rotStore[i] = new Quaternion();
+            posStore[i] = new Vector3f();
+            cStates[i] = new VRControllerState_t();
+            cStates[i].setAutoSynch(false);
+            cStates[i].setAutoRead(false);
+            cStates[i].setAutoWrite(false);
+            lastCallAxis[i] = new Vector2f();
+            needsNewVelocity[i] = true;
+            needsNewAngVelocity[i] = true;
+            logger.config("  Input "+(i+1)+"/"+JOpenVRLibrary.k_unMaxTrackedDeviceCount+" binded.");
+        }        
+        
+        return true;
+    }
+    
+    @Override
+    public VRTrackedController getTrackedController(int index){
+    	if (trackedControllers != null){
+    		if ((trackedControllers.size() > 0) && (index < trackedControllers.size())){
+    			return trackedControllers.get(index);
+    		}
+    	}
+    	
+    	return null;
+    }
+    
+    @Override
+    public int getTrackedControllerCount() {
+        return controllerCount;
+    }
+    
+    @Override
+    public VRControllerState_t getRawControllerState(int index) {
+        if( isInputDeviceTracking(index) == false ) return null;
+        return cStates[controllerIndex[index]];
+    }
+    
+    //public Matrix4f getPoseForInputDevice(int index) {
+    //    if( isInputDeviceTracking(index) == false ) return null;
+    //    return OpenVR.poseMatrices[controllerIndex[index]];
+    //}
+    
+    @Override
+    public boolean isInputFocused() {
+        return ((VR_IVRSystem_FnTable)app.getVRHardware().getVRSystem()).IsInputFocusCapturedByAnotherProcess.apply() == 0;       
+    }
+    
+    @Override
+    public boolean isInputDeviceTracking(int index) {
+        if( index < 0 || index >= controllerCount ) return false;
+        return OpenVR.hmdTrackedDevicePoses[controllerIndex[index]].bPoseIsValid != 0;
+    }
+    
+    @Override
+    public Quaternion getOrientation(int index) {
+        if( isInputDeviceTracking(index) == false ) return null;
+        index = controllerIndex[index];
+        VRUtil.convertMatrix4toQuat(OpenVR.poseMatrices[index], rotStore[index]);
+        return rotStore[index];
+    }
+
+    @Override
+    public Vector3f getPosition(int index) {
+        if( isInputDeviceTracking(index) == false ) 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];
+    }
+    
+    @Override
+    public Quaternion getFinalObserverRotation(int index) {
+        VRViewManager vrvm = app.getVRViewManager();
+        if( vrvm == null || isInputDeviceTracking(index) == false ) return null;
+        Object obs = app.getObserver();
+        if( obs instanceof Camera ) {
+            tempq.set(((Camera)obs).getRotation());
+        } else {
+            tempq.set(((Spatial)obs).getWorldRotation());
+        }
+        return tempq.multLocal(getOrientation(index));
+    }
+    
+    @Override 
+    public Vector3f getFinalObserverPosition(int index) {
+        VRViewManager vrvm = app.getVRViewManager();
+        if( vrvm == null || isInputDeviceTracking(index) == false ) return null;
+        Object obs = app.getObserver();
+        Vector3f pos = getPosition(index);
+        if( obs instanceof Camera ) {
+            ((Camera)obs).getRotation().mult(pos, pos);
+            return pos.addLocal(((Camera)obs).getLocation());
+        } else {
+            ((Spatial)obs).getWorldRotation().mult(pos, pos);
+            return pos.addLocal(((Spatial)obs).getWorldTranslation());
+        }
+    }    
+    
+    @Override
+    public void triggerHapticPulse(int controllerIndex, float seconds) {
+        if( app.isInVR() == false || isInputDeviceTracking(controllerIndex) == false ) return;
+        // apparently only axis ID of 0 works
+        ((VR_IVRSystem_FnTable)app.getVRHardware().getVRSystem()).TriggerHapticPulse.apply(OpenVRInput.controllerIndex[controllerIndex],
+                                                                                                     0, (short)Math.round(3f * seconds / 1e-3f));
+    }
+    
+    @Override
+    public void updateConnectedControllers() {
+    	logger.config("Updating connected controllers.");
+    	controllerCount = 0;
+    	for(int i=0;i<JOpenVRLibrary.k_unMaxTrackedDeviceCount;i++) {
+    		if( ((OpenVR)app.getVRHardware()).getVRSystem().GetTrackedDeviceClass.apply(i) == JOpenVRLibrary.ETrackedDeviceClass.ETrackedDeviceClass_TrackedDeviceClass_Controller ) {
+    			
+    			String controllerName   = "Unknown";
+				String manufacturerName = "Unknown";
+				try {
+					controllerName = OpenVRUtil.getTrackedDeviceStringProperty(((OpenVR)app.getVRHardware()).getVRSystem(), i, JOpenVRLibrary.ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_TrackingSystemName_String);
+					manufacturerName = OpenVRUtil.getTrackedDeviceStringProperty(((OpenVR)app.getVRHardware()).getVRSystem(), i, JOpenVRLibrary.ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_ManufacturerName_String);
+				} catch (Exception e) {
+                  logger.log(Level.WARNING, e.getMessage(), e);
+				}
+    			
+    			controllerIndex[controllerCount] = i;
+    			
+    			// Send an Haptic pulse to the controller
+    			triggerHapticPulse(controllerCount, 1.0f);
+    			
+    			controllerCount++;
+    			logger.config("  Tracked controller "+(i+1)+"/"+JOpenVRLibrary.k_unMaxTrackedDeviceCount+" "+controllerName+" ("+manufacturerName+") attached.");
+    		} else {
+    			logger.config("  Controller "+(i+1)+"/"+JOpenVRLibrary.k_unMaxTrackedDeviceCount+" ignored.");
+    		}
+    	}
+    }
+
+    @Override
+    public void updateControllerStates() {
+    	for(int i=0;i<controllerCount;i++) {
+    		int index = controllerIndex[i];
+    		((OpenVR)app.getVRHardware()).getVRSystem().GetControllerState.apply(index, cStates[index], 5);
+    		cStates[index].readField("ulButtonPressed");
+    		cStates[index].readField("rAxis");
+    		needsNewVelocity[index] = true;
+    		needsNewAngVelocity[index] = true;
+    	}
+    }
+
+	@Override
+	public VRAppState getVRAppState() {
+		return app;
+	}
+
+}

+ 196 - 0
jme3-vr/src/main/java/com/jme3/input/vr/VRAPI.java

@@ -0,0 +1,196 @@
+/*
+ * 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.VRAppState;
+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;
+
+/**
+ * An interface that represents a VR system. This interface has to be implemented in order to wrap underlying VR system (OpenVR, OSVR, ...)
+ * @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 interface VRAPI {
+    
+	/**
+	 * Initialize this object from a VR system. All the native bindings to underlying VR system should be done within this method.
+	 * @return <code>true</code> if the initialization is a success and <code>false</code> otherwise.
+	 */
+    public boolean initialize();
+    
+    /**
+     * Initialize the VR compositor that will be used for rendering.
+     * @param allowed <code>true</code> if the use of VR compositor is allowed and <code>false</code> otherwise.
+     * @return <code>true</code> if the initialization is a success and <code>false</code> otherwise.
+     */
+    public boolean initVRCompositor(boolean allowed);
+    
+    /**
+     * Get the {@link VRAppState VR app state} to which this api is attached.
+     * @return the VR app state to which this input is attached.
+     */
+    public VRAppState getVRAppState();
+    
+    /**
+     * Get the object that wraps natively the VR system.
+     * @return the object that wraps natively the VR system.
+     */
+    public Object getVRSystem();
+    
+    /**
+     * Get the object that wraps natively the VR compositor.
+     * @return the object that wraps natively the VR system.
+     */
+    public Object getCompositor();
+    
+    /**
+     * Get the name of the underlying VR system.
+     * @return the name of the underlying VR system.
+     */
+    public String getName();
+    
+    /**
+     * Get the input provided by the underlying VR system.
+     * @return the input provided by the underlying VR system.
+     */
+    public VRInputAPI getVRinput();
+    
+    /**
+     * Do not use. Prefers the preconfigure routine from the VRApplication.
+     * @param set <code>true</code> if the eyes has to be flipped and <code>false</code> otherwise.
+     */
+    public void _setFlipEyes(boolean set);
+    
+    /**
+     * Set if latency information has to be logged.
+     * @param set <code>true</code> if latency information has to be logged and <code>false</code> otherwise.
+     */
+    public void printLatencyInfoToConsole(boolean set);
+
+    /**
+     * Get the Head Mounted Device (HMD) display frequency.
+     * @return the Head Mounted DEvice (HMD) display frequency.
+     */
+    public int getDisplayFrequency();
+    
+    /**
+     * Close the link with underlying VR system and free all attached resources.
+     */
+    public void destroy();
+
+    /**
+     * Check if the VR API is initialized.
+     * @return <code>true</code> if the VR API is initialized and <code>false</code> otherwise.
+     * @see #initialize()
+     */
+    public boolean isInitialized();
+
+    /**
+     * Reset the VR system.
+     */
+    public void reset();
+
+    /**
+     * Get the size of an Head Mounted Device (HMD) rendering area in pixels.
+     * @param store the size of an Head Mounted Device (HMD) rendering area in pixels (modified).
+     */
+    public void getRenderSize(Vector2f store);
+    
+    //public float getFOV(int dir);
+
+    /**
+     * Get the Head Mounted Device (HMD) interpupilar distance in meters.
+     * @return the Head Mounted Device (HMD) interpupilar distance in meters.
+     */
+    public float getInterpupillaryDistance();
+    
+    /**
+     * Get the Head Mounted Device (HMD) orientation.
+     * @return the Head Mounted Device (HMD) orientation.
+     */
+    public Quaternion getOrientation();
+
+    /**
+     * Get the Head Mounted Device (HMD) position.
+     * @return the Head Mounted Device (HMD) orientation.
+     */
+    public Vector3f getPosition();
+    
+    /**
+     * Get the Head Mounted Device (HMD) position and orientation.
+     * @param storePos the Head Mounted Device (HMD) position (modified).
+     * @param storeRot the Head Mounted Device (HMD) rotation (modified).
+     */
+    public void getPositionAndOrientation(Vector3f storePos, Quaternion storeRot);
+    
+    /**
+     * Update Head Mounted Device (HMD) pose internal storage. This method should be called before other calls to HMD position/orientation access.
+     */
+    public void updatePose();
+
+    /**
+     * Get the Head Mounted Device (HMD) left eye projection matrix.
+     * @param cam the camera attached to the left eye.
+     * @return the Head Mounted Device (HMD) left eye projection matrix.
+     */
+    public Matrix4f getHMDMatrixProjectionLeftEye(Camera cam);
+        
+    /**
+     * Get the Head Mounted Device (HMD) right eye projection matrix.
+     * @param cam the camera attached to the right eye.
+     * @return the Head Mounted Device (HMD) right eye projection matrix.
+     */
+    public Matrix4f getHMDMatrixProjectionRightEye(Camera cam);
+    
+    /**
+     * Get the Head Mounted Device (HMD) left eye pose (position of the eye from the head) as a {@link Vector3f vector}.
+     * @return the Head Mounted Device (HMD) left eye pose as a {@link Vector3f vector}.
+     */
+    public Vector3f getHMDVectorPoseLeftEye();
+    
+    /**
+     * Get the Head Mounted Device (HMD) right eye pose (position of the eye from the head) as a {@link Vector3f vector}.
+     * @return the Head Mounted Device (HMD) right eye pose as a {@link Vector3f vector}.
+     */
+    public Vector3f getHMDVectorPoseRightEye();
+    
+    /**
+     * Returns the transform between the view space and left eye space. 
+     * Eye space is the per-eye flavor of view space that provides stereo disparity. 
+     * Instead of Model * View * Projection the model is Model * View * Eye * Projection. 
+     * Normally View and Eye will be multiplied together and treated as View.
+     * This matrix incorporates the user's interpupillary distance (IPD).
+     * @return the transform between the view space and eye space. 
+     */
+    public Matrix4f getHMDMatrixPoseLeftEye();
+    
+    /**
+     * Returns the transform between the view space and right eye space. 
+     * Eye space is the per-eye flavor of view space that provides stereo disparity. 
+     * Instead of Model * View * Projection the model is Model * View * Eye * Projection. 
+     * Normally View and Eye will be multiplied together and treated as View.
+     * This matrix incorporates the user's interpupillary distance (IPD).
+     * @return the transform between the view space and eye space. 
+     */
+    public Matrix4f getHMDMatrixPoseRightEye();
+    
+    /**
+     * Get the Head Mounted Device (HMD) type.
+     * @return the Head Mounted Device (HMD) type.
+     */
+    public HmdType getType();
+    
+    /**
+     * Get the seated to absolute position.
+     * @return the seated to absolute position.
+     */
+    public Vector3f getSeatedToAbsolutePosition();
+    
+}

+ 61 - 0
jme3-vr/src/main/java/com/jme3/input/vr/VRBounds.java

@@ -0,0 +1,61 @@
+package com.jme3.input.vr;
+
+import com.jme3.math.Vector2f;
+import com.jme3.system.jopenvr.JOpenVRLibrary;
+import com.jme3.system.jopenvr.VR_IVRChaperone_FnTable;
+import com.sun.jna.ptr.FloatByReference;
+
+import java.util.logging.Logger;
+
+/**
+ * A class that represents VR world bounds.
+ * @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 VRBounds {
+
+	private static Logger logger = Logger.getLogger(VRBounds.class.getName());
+	
+    private static VR_IVRChaperone_FnTable vrChaperone;
+    private static Vector2f playSize;
+    
+    /**
+     * Initialize the VR bounds.
+     * @return <code>true</code> if the initialization is a success and <code>false</code> otherwise.
+     */
+    public static boolean init() {
+    	
+    	logger.config("Initialize VR bounds...");
+    	
+        if( vrChaperone == null ) {
+            vrChaperone = new VR_IVRChaperone_FnTable(JOpenVRLibrary.VR_GetGenericInterface(JOpenVRLibrary.IVRChaperone_Version, OpenVR.hmdErrorStore).getPointer());
+            if( vrChaperone != null ) {
+                vrChaperone.setAutoSynch(false);
+                vrChaperone.read();
+                FloatByReference fbX = new FloatByReference();
+                FloatByReference fbZ = new FloatByReference();
+                vrChaperone.GetPlayAreaSize.apply(fbX, fbZ);
+                playSize = new Vector2f(fbX.getValue(), fbZ.getValue());
+                
+                logger.config("Initialize VR bounds [SUCCESS]");
+                return true; // init success
+            }
+            
+            logger.warning("Initialize VR bounds [FAILED].");
+            return false; // failed to init
+        }
+        
+        logger.config("Initialize VR bounds already done.");
+        return true; // already initialized
+    }
+    
+    /**
+     * Get the size of the VR world.
+     * @return the size of the VR world.
+     */
+    public static Vector2f getPlaySize() {
+        return playSize;
+    }
+    
+}
+

+ 205 - 0
jme3-vr/src/main/java/com/jme3/input/vr/VRInputAPI.java

@@ -0,0 +1,205 @@
+/*
+ * 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.VRAppState;
+import com.jme3.app.VRApplication;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Vector2f;
+import com.jme3.math.Vector3f;
+
+/**
+ * An interface that represents a VR input (typically a VR device such as a controller).
+ * @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 interface VRInputAPI {
+
+	/**
+	 * Check if the given button is down (more generally if the given input type is activated).
+	 * @param controllerIndex the index of the controller to check.
+	 * @param checkButton the button / input to check.
+	 * @return <code>true</code> if the button / input is down / activated and <code>false</code> otherwise.
+	 */
+    public boolean isButtonDown(int controllerIndex, VRInputType checkButton);
+    
+    /**
+     * Check if the given button / input from the given controller has been just pressed / activated.
+     * @param controllerIndex the index of the controller.
+     * @param checkButton the button / input to check.
+     * @return <code>true</code> if the given button / input from the given controller has been just pressed / activated and <code>false</code> otherwise.
+     */
+    public boolean wasButtonPressedSinceLastCall(int controllerIndex, VRInputType checkButton);
+    
+    /**
+     * Reset the current activation of the inputs. After a call to this method, all input activation is considered as new activation.
+     * @see #wasButtonPressedSinceLastCall(int, VRInputType)
+     */
+    public void resetInputSinceLastCall();
+    
+    /**
+     * Get the controller axis delta from the last value.
+     * @param controllerIndex the index of the controller.
+     * @param forAxis the axis.
+     * @return the controller axis delta from the last call.
+     */
+    public Vector2f getAxisDeltaSinceLastCall(int controllerIndex, VRInputType forAxis);
+    
+    /**
+     * Get the controller velocity on all axes.
+     * @param controllerIndex the index of the controller.
+     * @return the controller velocity on all axes.
+     * @see #getAngularVelocity(int)
+     */
+    public Vector3f getVelocity(int controllerIndex);
+    
+    /**
+     * Get the controller angular velocity on all axes.
+     * @param controllerIndex the index of the controller.
+     * @return the controller angular velocity on all axes.
+     * @see #getVelocity(int)
+     */
+    public Vector3f getAngularVelocity(int controllerIndex);
+    
+    /**
+     * Get the axis value for the given input on the given controller. 
+     * This value is the {@link #getAxisRaw(int, VRInputType) raw value} multiplied by the  {@link #getAxisMultiplier() axis multiplier}.
+     * @param controllerIndex the index of the controller.
+     * @param forAxis the axis.
+     * @return the axis value for the given input on the given controller.
+     * @see #getAxisRaw(int, VRInputType)
+     * @see #getAxisMultiplier()
+     */
+    public Vector2f getAxis(int controllerIndex, VRInputType forAxis);
+    
+    /**
+     * Get the axis value for the given input on the given controller. 
+     * @param controllerIndex the index of the controller.
+     * @param forAxis the axis.
+     * @return the axis value for the given input on the given controller.
+     * @see #getAxis(int, VRInputType)
+     */
+    public Vector2f getAxisRaw(int controllerIndex, VRInputType forAxis);
+
+    /**
+     * Initialize the input.
+     * @return <code>true</code> if the initialization is successful and <code>false</code> otherwise.
+     */
+    public boolean init();
+    
+    /**
+     * Get the number of tracked controller (for example an hand controllers) attached to the VR system.
+     * @return the number of controller attached to the VR system.
+     * @see #getTrackedController(int)
+     */
+    public int getTrackedControllerCount();
+    
+    /**
+     * Get the tracked controller (for example an hand controllers) that is attached to the VR system.
+     * @param index the index of the controller.
+     * @return the tracked controller (for example an hand controllers) that is attached to the VR system.
+     * @see #getTrackedControllerCount()
+     */
+    public VRTrackedController getTrackedController(int index);
+    
+    /**
+     * Update the connected controllers. 
+     * This method should be used just after the initialization of the input.
+     */
+    public void updateConnectedControllers();
+    
+    /**
+     * Update the controller states.
+     * This method should be called before accessing any controller data.
+     */
+    public void updateControllerStates();
+    
+    /**
+     * Get the native wrapping of a controller state.
+     * @param index the index of the controller.
+     * @return the native wrapping of a controller state.
+     */
+    public Object getRawControllerState(int index);
+    
+    /**
+     * Swap the two hands (exchange the hands controller 1 & 2 indices).
+     */
+    public void swapHands();
+    
+    /**
+     * Get the controller axis multiplier. 
+     * The controller axis raw data (trackpad, trigger, ...) value is multiplied by the one given in parameter.
+     * @return the controller axis multiplier. 
+     * @see #setAxisMultiplier(float)
+     */
+    public float getAxisMultiplier();
+    
+    /**
+     * Set the controller axis multiplier. 
+     * The controller axis raw data (trackpad, trigger, ...) value is multiplied by the one given in parameter.
+     * @param set the controller axis multiplier. 
+     * @see #getAxisMultiplier()
+     */
+    public void setAxisMultiplier(float set);
+    
+    //public Matrix4f getPoseForInputDevice(int index);
+    
+    /**
+     * Check if the VR system has the focus and if it's not used by other process.
+     * @return <code>true</code> if the VR system has the focus and <code>false</code> otherwise.
+     */
+    public boolean isInputFocused();
+    
+    /**
+     * Check if the input device is actually tracked (i-e if we can obtain a pose from the input).
+     * @param index the index of the controller.
+     * @return <code>true</code> if the input device is actually tracked and <code>false</code> otherwise.
+     */
+    public boolean isInputDeviceTracking(int index);
+    
+    /**
+     * Get the orientation of the input.
+     * @param index the index of the controller.
+     * @return the orientation of the input.
+     */
+    public Quaternion getOrientation(int index);
+
+    /**
+     * Get the position of the input.
+     * @param index the index of the controller.
+     * @return the position of the input.
+     */
+    public Vector3f getPosition(int index);
+    
+    /**
+     * Get where is the controller pointing, after all rotations are combined.
+     * This position should include includes observer rotation from the VR application.
+     * @param index the index of the controller.
+     * @return the rotation of the input after all positional tracking is complete.
+     */
+    public Quaternion getFinalObserverRotation(int index);
+    
+    /**
+     * Get the position of the input after all positional tracking is complete.
+     * This position should include includes observer position from the VR application.
+     * @param index the index of the controller.
+     * @return the position of the input after all positional tracking is complete.
+     */
+    public Vector3f getFinalObserverPosition(int index);
+    
+    /**
+     * Trigger an haptic pulse on the selected controller for the duration given in parameters (in seconds).
+     * @param controllerIndex the index of the controller.
+     * @param seconds the duration of the pulse in seconds.
+     */
+    public void triggerHapticPulse(int controllerIndex, float seconds);
+    
+    /**
+     * Get the {@link VRAppState VR app state} to which this api is attached.
+     * @return the VR app state to which this input is attached.
+     */
+    public VRAppState getVRAppState();
+}

+ 51 - 0
jme3-vr/src/main/java/com/jme3/input/vr/VRInputType.java

@@ -0,0 +1,51 @@
+package com.jme3.input.vr;
+
+/**
+ * The type of a VR input. This enumeration enables to determine which part of the VR device is involved within input callback.
+ * @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 enum VRInputType {
+	
+	/**
+	 * an HTC vive trigger axis (about <a href="https://www.vive.com/us/support/category_howto/720435.html">Vive controller</a>).
+	 */
+    ViveTriggerAxis(0), 
+    
+	/**
+	 * an HTC vive trackpad axis (about <a href="https://www.vive.com/us/support/category_howto/720435.html">Vive controller</a>).
+	 */
+    ViveTrackpadAxis(1), 
+    
+	/**
+	 * an HTC vive grip button (about <a href="https://www.vive.com/us/support/category_howto/720435.html">Vive controller</a>).
+	 */
+    ViveGripButton(2), 
+    
+	/**
+	 * an HTC vive menu button (about <a href="https://www.vive.com/us/support/category_howto/720435.html">Vive controller</a>).
+	 */
+    ViveMenuButton(3);
+    
+    /**
+     * The value that codes the input type.
+     */
+	private final int value;
+    
+	/**
+	 * Construct a new input type with the given code.
+	 * @param value the code of the input type.
+	 */
+    private VRInputType(int value) {
+        this.value = value;
+    }
+
+    /**
+     * Get the value (code) of the input type.
+     * @return the value (code) of the input type.
+     */
+    public int getValue() {
+        return value;
+    }        
+}

+ 10 - 0
jme3-vr/src/main/java/com/jme3/input/vr/VRTrackedController.java

@@ -0,0 +1,10 @@
+package com.jme3.input.vr;
+
+/**
+ * TODO
+ * @author Julien Seinturier - (c) 2016 - JOrigin project - <a href="http://www.jorigin.org">http:/www.jorigin.org</a>
+ *
+ */
+public interface VRTrackedController {
+  
+}

+ 159 - 0
jme3-vr/src/main/java/com/jme3/post/CartoonSSAO.java

@@ -0,0 +1,159 @@
+/*
+* To change this template, choose Tools | Templates
+* and open the template in the editor.
+*/
+package com.jme3.post;
+
+import com.jme3.asset.AssetManager;
+import com.jme3.material.Material;
+import com.jme3.math.Vector2f;
+import com.jme3.math.Vector3f;
+import com.jme3.post.Filter;
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.ViewPort;
+import com.jme3.renderer.queue.RenderQueue;
+import com.jme3.texture.Image.Format;
+
+/**
+ * A Cartoon Screen Space Ambient Occlusion filter with instance rendering capabilities.
+ * @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 CartoonSSAO extends Filter{
+    private Pass normalPass;
+    private Vector3f frustumCorner;
+    private Vector2f frustumNearFar;
+    private boolean useOutline = true;
+    private float downsample = 1f, applyDistance = 0.0005f;
+
+    private boolean instancedRendering = false;
+    
+    RenderManager renderManager;
+    ViewPort viewPort;
+
+    /**
+    * Create a Screen Space Ambient Occlusion Filter.
+    * @param instancedRendering <code>true</code> if this filter has to use instance rendering and <code>false</code> (default) otherwise.
+    */
+    public CartoonSSAO(boolean instancedRendering) {
+        super("CartoonSSAO");
+        this.instancedRendering = instancedRendering;
+    }
+
+    /**
+    * Create a Screen Space Ambient Occlusion Filter.
+    * @param downsample factor to divide resolution by for filter, >1 increases speed but degrades quality.
+    * @param instancedRendering <code>true</code> if this filter has to use instance rendering and <code>false</code> (default) otherwise.
+    */
+    public CartoonSSAO(float downsample, boolean instancedRendering) {
+        this(instancedRendering);
+        this.downsample = downsample;
+    }
+    
+    /**
+     * Create a Screen Space Ambient Occlusion Filter from the given one (by copy).
+     * @param cloneFrom the original filter.
+     */
+    public CartoonSSAO(CartoonSSAO cloneFrom) {
+        this(cloneFrom.downsample, cloneFrom.instancedRendering);
+    }
+
+    @Override
+    protected boolean isRequiresDepthTexture() {
+        return true;
+    }
+
+    @Override
+    protected void postQueue(RenderQueue renderQueue) {
+        PreNormalCaching.getPreNormals(renderManager, normalPass, viewPort);
+    }
+    
+    /**
+     * Set if outline has to be enabled.
+     * @param set <code>true</code> if the outline has to be enabled and <code>false</code> otherwise.
+     * @see #isOutlineEnabled()
+     */
+    public void setOutlineEnabled(boolean set) {
+        useOutline = set;
+        if( material != null ) {
+            if( useOutline ) {
+                material.clearParam("disableOutline");
+            } else {
+                material.setBoolean("disableOutline", true);
+            }
+        }
+    }
+    
+    /**
+     * Is outline rendering is enabled. 
+     * @return <code>true</code> if the outline is enabled and <code>false</code> otherwise.
+     * @see #setOutlineEnabled(boolean)
+     */
+    public boolean isOutlineEnabled() {
+        return useOutline;
+    }
+    
+    /**
+     * Set the down sampling value.
+     * @param downsample the down sampling value.
+     * @see #getDownsampling()
+     */
+    public void setDownsampling(float downsample) {
+        this.downsample = downsample;
+    }
+    
+    /**
+     * Get the down sampling value.
+     * @return the down sampling value.
+     * @see #setDownsampling(float)
+     */
+    public float getDownsampling() {
+        return this.downsample;
+    }
+
+    @Override
+    protected Material getMaterial() {
+        return material;
+    }
+
+    /**
+     * Set the distance of the material.
+     * @param dist the distance of the material.
+     */
+    public void setDistance(float dist) {
+        applyDistance = dist;
+        if( material != null ) material.setFloat("Distance", dist);
+    }
+    
+    @Override
+    protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
+        this.renderManager = renderManager;
+        this.viewPort = vp;
+
+        int screenWidth = Math.round(w / downsample);
+        int screenHeight = Math.round(h / downsample);
+
+        normalPass = new Pass();
+        normalPass.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA8, Format.Depth);
+
+        frustumNearFar = new Vector2f();
+
+        float farY = (vp.getCamera().getFrustumTop() / vp.getCamera().getFrustumNear()) * vp.getCamera().getFrustumFar();
+        float farX = farY * ((float) screenWidth / (float) screenHeight);
+        frustumCorner = new Vector3f(farX, farY, vp.getCamera().getFrustumFar());
+        frustumNearFar.x = vp.getCamera().getFrustumNear();
+        frustumNearFar.y = vp.getCamera().getFrustumFar();
+
+        //ssao Pass
+        material = new Material(manager, "Common/MatDefs/VR/CartoonSSAO.j3md");
+        material.setTexture("Normals", normalPass.getRenderedTexture());        
+
+        material.setVector3("FrustumCorner", frustumCorner);
+        material.setVector2("FrustumNearFar", frustumNearFar);
+        material.setFloat("Distance", applyDistance);
+        if( useOutline == false ) material.setBoolean("disableOutline", true);
+        if( instancedRendering ) material.setBoolean("useInstancing", true);
+    }
+
+}

+ 210 - 0
jme3-vr/src/main/java/com/jme3/post/OpenVRFilter.java

@@ -0,0 +1,210 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.post;
+
+import com.jme3.app.VRApplication;
+import com.jme3.asset.AssetManager;
+import com.jme3.material.Material;
+import com.jme3.post.Filter;
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.Renderer;
+import com.jme3.renderer.ViewPort;
+import com.jme3.scene.Mesh;
+import com.jme3.scene.VertexBuffer;
+import com.jme3.system.jopenvr.DistortionCoordinates_t;
+import com.jme3.system.jopenvr.JOpenVRLibrary;
+import com.jme3.system.jopenvr.VR_IVRSystem_FnTable;
+import com.jme3.texture.FrameBuffer;
+
+/**
+ * DO NOT USE
+ * @author phr00t
+ * @deprecated DO NOT USE
+ */
+@Deprecated
+public class OpenVRFilter extends Filter {
+
+    private Mesh distortionMesh;
+    
+    private VRApplication application = null;
+    
+    /**
+     * DO NOT USE
+     * @param application the VR application.
+     */
+    public OpenVRFilter(VRApplication application) {
+        this.application = application;
+    }
+    
+    /**
+     * DO NOT USE
+     * @return the distortion mesh.
+     */
+    public Mesh getDistortionMesh() {
+        return distortionMesh;
+    }
+
+    @Override
+    protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
+        material = new Material(manager, "Common/MatDefs/VR/OpenVR.j3md");
+        configureDistortionMesh();
+    }
+
+    @Override
+    protected Material getMaterial() {
+        return material;
+
+    }
+    
+    @Override
+    protected void preFrame(float tpf) {
+        super.preFrame(tpf);
+    }
+
+    @Override
+    protected void postFrame(RenderManager renderManager, ViewPort viewPort, FrameBuffer prevFilterBuffer, FrameBuffer sceneBuffer) {
+        super.postFrame(renderManager, viewPort, prevFilterBuffer, sceneBuffer);
+    }
+
+    @Override
+    protected void postFilter(Renderer r, FrameBuffer buffer) {
+        super.postFilter(r, buffer);
+    }
+    
+    /*
+        function converted from:
+        https://github.com/ValveSoftware/openvr/blob/master/samples/hellovr_opengl/hellovr_opengl_main.cpp#L1335
+    */
+    private void configureDistortionMesh() {        
+        float m_iLensGridSegmentCountH = 43, m_iLensGridSegmentCountV = 43;
+
+	float w = 1f / m_iLensGridSegmentCountH - 1f;
+	float h = 1f / m_iLensGridSegmentCountV - 1f;
+
+	float u, v;
+
+        distortionMesh = new Mesh();
+        float verts[] = new float[(int)(m_iLensGridSegmentCountV * m_iLensGridSegmentCountH) * 3];
+        
+        float texcoordR[] = new float[(int)(m_iLensGridSegmentCountV * m_iLensGridSegmentCountH) * 2];
+        float texcoordG[] = new float[(int)(m_iLensGridSegmentCountV * m_iLensGridSegmentCountH) * 2];
+        float texcoordB[] = new float[(int)(m_iLensGridSegmentCountV * m_iLensGridSegmentCountH) * 2];        
+        
+        int vertPos = 0, coordPos = 0;
+
+	//left eye distortion verts
+	float Xoffset = -1f;
+	for( int y=0; y<m_iLensGridSegmentCountV; y++ )
+	{
+		for( int x=0; x<m_iLensGridSegmentCountH; x++ )
+		{
+			u = x*w; v = 1-y*h;
+			verts[vertPos] = Xoffset+u; // x
+                        verts[vertPos+1] = -1+2*y*h; // y
+                        verts[vertPos+2] = 0f; // z
+                        vertPos += 3;
+
+			DistortionCoordinates_t dc0 = new DistortionCoordinates_t();
+		    ((VR_IVRSystem_FnTable)application.getVRHardware().getVRSystem()).ComputeDistortion.apply(JOpenVRLibrary.EVREye.EVREye_Eye_Left, u, v, dc0);
+
+			texcoordR[coordPos]   = dc0.rfRed[0];
+                        texcoordR[coordPos+1] = 1 - dc0.rfRed[1];
+			texcoordG[coordPos]   = dc0.rfGreen[0];
+                        texcoordG[coordPos+1] = 1 - dc0.rfGreen[1];
+			texcoordB[coordPos]   = dc0.rfBlue[0];
+                        texcoordB[coordPos+1] = 1 - dc0.rfBlue[1];                        
+                        coordPos+=2;                        
+		}
+	}
+
+	//right eye distortion verts
+	Xoffset = 0;
+	for( int y=0; y<m_iLensGridSegmentCountV; y++ )
+	{
+		for( int x=0; x<m_iLensGridSegmentCountH; x++ )
+		{
+			u = x*w; v = 1-y*h;
+			verts[vertPos] = Xoffset+u; // x
+                        verts[vertPos+1] = -1+2*y*h; // y
+                        verts[vertPos+2] = 0f; // z
+                        vertPos += 3;
+
+            DistortionCoordinates_t dc0 = new DistortionCoordinates_t();
+			((VR_IVRSystem_FnTable)application.getVRHardware().getVRSystem()).ComputeDistortion.apply(JOpenVRLibrary.EVREye.EVREye_Eye_Right, u, v, dc0);
+
+			texcoordR[coordPos]   = dc0.rfRed[0];
+                        texcoordR[coordPos+1] = 1 - dc0.rfRed[1];
+			texcoordG[coordPos]   = dc0.rfGreen[0];
+                        texcoordG[coordPos+1] = 1 - dc0.rfGreen[1];
+			texcoordB[coordPos]   = dc0.rfBlue[0];
+                        texcoordB[coordPos+1] = 1 - dc0.rfBlue[1];                        
+                        coordPos+=2;                        
+		}
+	}
+        
+        // have UV coordinates & positions, now to setup indices
+        
+	//std::vector<GLushort> vIndices;
+        int[] indices = new int[(int)((m_iLensGridSegmentCountV - 1) * (m_iLensGridSegmentCountH - 1)) * 6];
+        int indexPos = 0;
+	int a,b,c,d;
+
+	int offset = 0;
+	for( int y=0; y<m_iLensGridSegmentCountV-1; y++ )
+	{
+		for( int x=0; x<m_iLensGridSegmentCountH-1; x++ )
+		{
+			a = (int)(m_iLensGridSegmentCountH*y+x +offset);
+			b = (int)(m_iLensGridSegmentCountH*y+x+1 +offset);
+			c = (int)((y+1)*m_iLensGridSegmentCountH+x+1 +offset);
+			d = (int)((y+1)*m_iLensGridSegmentCountH+x +offset);
+                        
+                        indices[indexPos] = a;
+                        indices[indexPos+1] = b;
+                        indices[indexPos+2] = c;
+                        
+                        indices[indexPos+3] = a;
+                        indices[indexPos+4] = c;
+                        indices[indexPos+5] = d;
+                        
+                        indexPos += 6;
+		}
+	}
+
+	offset = (int)(m_iLensGridSegmentCountH * m_iLensGridSegmentCountV);
+	for( int y=0; y<m_iLensGridSegmentCountV-1; y++ )
+	{
+		for( int x=0; x<m_iLensGridSegmentCountH-1; x++ )
+		{
+			a = (int)(m_iLensGridSegmentCountH*y+x +offset);
+			b = (int)(m_iLensGridSegmentCountH*y+x+1 +offset);
+			c = (int)((y+1)*m_iLensGridSegmentCountH+x+1 +offset);
+			d = (int)((y+1)*m_iLensGridSegmentCountH+x +offset);
+                        
+                        indices[indexPos] = a;
+                        indices[indexPos+1] = b;
+                        indices[indexPos+2] = c;
+                        
+                        indices[indexPos+3] = a;
+                        indices[indexPos+4] = c;
+                        indices[indexPos+5] = d;
+                        
+                        indexPos += 6;
+		}
+	}        
+        
+        // OK, create the mesh        
+        distortionMesh.setBuffer(VertexBuffer.Type.Position,  3, verts);
+        distortionMesh.setBuffer(VertexBuffer.Type.Index,     1, indices);
+        distortionMesh.setBuffer(VertexBuffer.Type.TexCoord,  2, texcoordR);
+        
+        // TODO: are TexCoord2 & TexCoord3 even implemented in jME3?
+        distortionMesh.setBuffer(VertexBuffer.Type.TexCoord2, 2, texcoordG);
+        distortionMesh.setBuffer(VertexBuffer.Type.TexCoord3, 2, texcoordB);
+        
+        // TODO: make sure this distortion mesh is used instead of the fullscreen quad
+        // when filter gets rendered.. might require changes to jME3 core..?
+    }    
+}

+ 71 - 0
jme3-vr/src/main/java/com/jme3/post/PreNormalCaching.java

@@ -0,0 +1,71 @@
+/*
+ * 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.post;
+
+import com.jme3.post.Filter.Pass;
+import com.jme3.renderer.Caps;
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.Renderer;
+import com.jme3.renderer.ViewPort;
+import com.jme3.texture.FrameBuffer;
+
+/**
+ * Pre normal caching class.
+ * @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 PreNormalCaching {
+    
+    private static FrameBuffer cachedPreNormals;
+    private static int lastNormalPassesCount, curCount;
+    
+    /**
+     * Get pre-normals from the given rendering.
+     * @param renderManager the render manager.
+     * @param normalPass the normal pass.
+     * @param viewPort the viewport.
+     */
+    public static void getPreNormals(RenderManager renderManager, Pass normalPass, ViewPort viewPort) {
+        curCount++;
+        // do we already have a valid cache to set the framebuffer to?
+        Renderer r = renderManager.getRenderer();
+        if( cachedPreNormals != null ) {
+            r.copyFrameBuffer(cachedPreNormals, normalPass.getRenderFrameBuffer(), false);
+        } else {
+            // lets make the prenormals
+            r.setFrameBuffer(normalPass.getRenderFrameBuffer());
+            renderManager.getRenderer().clearBuffers(true, true, true);
+            if( renderManager.getRenderer().getCaps().contains(Caps.GLSL150) ) {
+                renderManager.setForcedTechnique("PreNormalPass15");
+            } else {
+                renderManager.setForcedTechnique("PreNormalPass");                
+            }
+            renderManager.renderViewPortQueues(viewPort, false);
+            renderManager.setForcedTechnique(null);
+            // if we should cache this, do it now
+            if( lastNormalPassesCount > 1 ) {
+                cachedPreNormals = normalPass.getRenderFrameBuffer();
+            }
+        }
+        renderManager.getRenderer().setFrameBuffer(viewPort.getOutputFrameBuffer());
+    }
+    
+   /**
+    * Reset the cache
+    * @param stereo <code>true</code> if the rendering is stereo based and <code>false</code> otherwise.
+    */
+    public static void resetCache(boolean stereo) {
+        if( stereo == false ) {
+            // only use this feature if we are NOT in VR
+            // we can't use the same normal information for another eye,
+            // because it will be different!
+            lastNormalPassesCount = curCount;
+        }
+        cachedPreNormals = null;
+        curCount = 0;
+    }
+    
+}

+ 332 - 0
jme3-vr/src/main/java/com/jme3/shadow/AbstractShadowFilterVR.java

@@ -0,0 +1,332 @@
+package com.jme3.shadow;
+
+/*
+ * Copyright (c) 2009-2012 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import com.jme3.asset.AssetManager;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.material.Material;
+import com.jme3.material.RenderState;
+import com.jme3.math.Matrix4f;
+import com.jme3.math.Vector4f;
+import com.jme3.post.Filter;
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.ViewPort;
+import com.jme3.renderer.queue.RenderQueue;
+import com.jme3.shadow.CompareMode;
+import com.jme3.shadow.EdgeFilteringMode;
+import com.jme3.texture.FrameBuffer;
+
+import java.io.IOException;
+
+/**
+ * Generic abstract filter that holds common implementations for the different
+ * shadow filters.
+ *
+ * @author Rémy Bouquet aka Nehon
+ * @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>
+ * @param <T> the type of the underlying renderer (subclass of {@link AbstractShadowRendererVR}).
+ */
+public abstract class AbstractShadowFilterVR<T extends AbstractShadowRendererVR> extends Filter {
+
+    protected T shadowRenderer;
+    protected ViewPort viewPort;
+
+    /**
+     * Abstract class constructor
+     *
+     * @param manager the application asset manager
+     * @param shadowMapSize the size of the rendered shadowmaps (512,1024,2048,
+     * etc...)
+     * @param nbShadowMaps the number of shadow maps rendered (the more shadow
+     * maps the more quality, the less fps).
+     * @param shadowRenderer the shadowRenderer to use for this Filter
+     */
+    @SuppressWarnings("all")
+    protected AbstractShadowFilterVR(AssetManager manager, int shadowMapSize, T shadowRenderer) {
+        super("Post Shadow");
+        material = new Material(manager, "Common/MatDefs/Shadow/PostShadowFilter.j3md");       
+        this.shadowRenderer = shadowRenderer;
+        this.shadowRenderer.setPostShadowMaterial(material);
+
+        //this is legacy setting for shadows with backface shadows
+        this.shadowRenderer.setRenderBackFacesShadows(true);
+    }
+
+    @SuppressWarnings("all")
+    protected AbstractShadowFilterVR(AssetManager manager, int shadowMapSize, T shadowRenderer, String useMatDef) {
+        super("Post Shadow");
+        material = new Material(manager, useMatDef);       
+        this.shadowRenderer = shadowRenderer;
+        this.shadowRenderer.setPostShadowMaterial(material);
+    }
+    
+    @Override
+    protected Material getMaterial() {
+        return material;
+    }
+
+    @Override
+    protected boolean isRequiresDepthTexture() {
+        return true;
+    }
+
+    /**
+     * Get the {@link Material material} used by this filter.
+     * @return the {@link Material material} used by this filter.
+     */
+    public Material getShadowMaterial() {       
+        return material;
+    }
+    
+    Vector4f tmpv = new Vector4f();
+
+    @Override
+    protected void preFrame(float tpf) {
+        shadowRenderer.preFrame(tpf);
+        material.setMatrix4("ViewProjectionMatrixInverse", viewPort.getCamera().getViewProjectionMatrix().invert());
+        Matrix4f m = viewPort.getCamera().getViewProjectionMatrix();
+        material.setVector4("ViewProjectionMatrixRow2", tmpv.set(m.m20, m.m21, m.m22, m.m23));
+
+    }
+
+    @Override
+    protected void postQueue(RenderQueue queue) {
+        shadowRenderer.postQueue(queue);
+         if(shadowRenderer.skipPostPass){
+             //removing the shadow map so that the post pass is skipped
+             material.setTexture("ShadowMap0", null);
+         }
+    }
+
+    @Override
+    protected void postFrame(RenderManager renderManager, ViewPort viewPort, FrameBuffer prevFilterBuffer, FrameBuffer sceneBuffer) {
+        if(!shadowRenderer.skipPostPass){
+            shadowRenderer.setPostShadowParams();
+        }
+    }
+
+    @Override
+    protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
+        shadowRenderer.needsfallBackMaterial = true;
+        shadowRenderer.initialize(renderManager, vp);
+        this.viewPort = vp;
+    }
+    
+      /**
+     * How far the shadows are rendered in the view
+     *
+     * @see #setShadowZExtend(float zFar)
+     * @return shadowZExtend
+     */
+    public float getShadowZExtend() {
+        return shadowRenderer.getShadowZExtend();
+    }
+
+    /**
+     * Set the distance from the eye where the shadows will be rendered default
+     * value is dynamically computed to the shadow casters/receivers union bound
+     * zFar, capped to view frustum far value.
+     *
+     * @param zFar the zFar values that override the computed one
+     */
+    public void setShadowZExtend(float zFar) {
+        shadowRenderer.setShadowZExtend(zFar);
+    }
+
+    /**
+     * Define the length over which the shadow will fade out when using a
+     * shadowZextend
+     *
+     * @param length the fade length in world units
+     */
+    public void setShadowZFadeLength(float length) {
+        shadowRenderer.setShadowZFadeLength(length);
+    }
+
+    /**
+     * get the length over which the shadow will fade out when using a
+     * shadowZextend
+     *
+     * @return the fade length in world units
+     */
+    public float getShadowZFadeLength() {
+        return shadowRenderer.getShadowZFadeLength();
+    }
+
+    /**
+     * returns the shdaow intensity
+     *
+     * @see #setShadowIntensity(float shadowIntensity)
+     * @return shadowIntensity
+     */
+    public float getShadowIntensity() {
+        return shadowRenderer.getShadowIntensity();
+    }
+
+    /**
+     * Set the shadowIntensity, the value should be between 0 and 1, a 0 value
+     * gives a bright and invisible shadow, a 1 value gives a pitch black
+     * shadow, default is 0.7
+     *
+     * @param shadowIntensity the darkness of the shadow
+     */
+    final public void setShadowIntensity(float shadowIntensity) {
+        shadowRenderer.setShadowIntensity(shadowIntensity);
+    }
+
+    /**
+     * returns the edges thickness <br>
+     *
+     * @see #setEdgesThickness(int edgesThickness)
+     * @return edgesThickness
+     */
+    public int getEdgesThickness() {
+        return shadowRenderer.getEdgesThickness();
+    }
+
+    /**
+     * Sets the shadow edges thickness. default is 1, setting it to lower values
+     * can help to reduce the jagged effect of the shadow edges
+     * @param edgesThickness the edge thickness.
+     */
+    public void setEdgesThickness(int edgesThickness) {
+        shadowRenderer.setEdgesThickness(edgesThickness);
+    }
+
+    /**
+     * isFlushQueues does nothing and is kept only for backward compatibility.
+     * @return <code>false</code>
+     * @deprecated does nothing and is kept only for backward compatibility.
+     */
+    @Deprecated
+    public boolean isFlushQueues() {
+        return shadowRenderer.isFlushQueues();
+    }
+
+    /**
+     * setFlushQueues does nothing now and is kept only for backward compatibility.
+     * @param flushQueues can be <code>true</code> or <code>false</code>.
+     * @deprecated does nothing now and is kept only for backward compatibility.
+     */
+    @Deprecated
+    public void setFlushQueues(boolean flushQueues) {}
+
+    /**
+     * Sets the shadow compare mode (see {@link CompareMode} for more info).
+     * @param compareMode the compare mode.
+     */
+    final public void setShadowCompareMode(CompareMode compareMode) {
+        shadowRenderer.setShadowCompareMode(compareMode);
+    }
+
+    /**
+     * Get the shadow compare mode.
+     *
+     * @return the shadow compare mode.
+     * @see CompareMode
+     */
+    public CompareMode getShadowCompareMode() {
+        return shadowRenderer.getShadowCompareMode();
+    }
+
+    /**
+     * Sets the filtering mode for shadow edges see {@link EdgeFilteringMode} for more info
+     * @param filterMode the filtering mode for shadow edges.
+     */
+    final public void setEdgeFilteringMode(EdgeFilteringMode filterMode) {
+        shadowRenderer.setEdgeFilteringMode(filterMode);
+    }
+
+    /**
+     *
+     * <b>WARNING</b> this parameter is defaulted to <code>true</code> for the shadow filter. Setting it to <code>true</code>, may produce edges artifacts on shadows.<br>
+     * <br>
+     * Set to <code>true</code> if you want back faces shadows on geometries.
+     * Note that back faces shadows will be blended over dark lighten areas and may produce overly dark lighting.<br>
+     *<br>
+     * Setting this parameter will override this parameter for <b>ALL</b> materials in the scene.
+     * This also will automatically adjust the face cull mode and the PolyOffset of the pre shadow pass.
+     * You can modify them by using {@link #getPreShadowForcedRenderState()}.<br>
+     * <br>
+     * If you want to set it differently for each material in the scene you have to use the ShadowRenderer instead
+     * of the shadow filter.
+     *
+     * @param renderBackFacesShadows <code>true</code> if back faces shadows on geometries have to be rendered and <code>false</code> otherwise.
+     */
+    public void setRenderBackFacesShadows(Boolean renderBackFacesShadows) {
+        shadowRenderer.setRenderBackFacesShadows(renderBackFacesShadows);
+    }
+
+    /**
+     * Is this filter renders back faces shadows.
+     * @return <code>true</code> if this filter renders back faces shadows and <code>false</code> otherwise.
+     */
+    public boolean isRenderBackFacesShadows() {
+        return shadowRenderer.isRenderBackFacesShadows();
+    }
+
+    /**
+     * Get the pre-shadows pass render state.
+     * use it to adjust the RenderState parameters of the pre shadow pass.
+     * Note that this will be overridden if the preShadow technique in the material has a ForcedRenderState
+     * @return the pre shadow render state.
+     */
+    public RenderState getPreShadowForcedRenderState() {
+        return shadowRenderer.getPreShadowForcedRenderState();
+    }
+
+
+    /**
+     * Get the the edge filtering mode.
+     * @return the edge filtering mode.
+     */
+    public EdgeFilteringMode getEdgeFilteringMode() {
+        return shadowRenderer.getEdgeFilteringMode();
+    }
+
+    @Override
+    public void write(JmeExporter ex) throws IOException {
+        super.write(ex);
+        //OutputCapsule oc = ex.getCapsule(this);
+
+    }
+
+    @Override
+    public void read(JmeImporter im) throws IOException {
+        super.read(im);
+        //InputCapsule ic = im.getCapsule(this);
+
+    }
+}

+ 834 - 0
jme3-vr/src/main/java/com/jme3/shadow/AbstractShadowRendererVR.java

@@ -0,0 +1,834 @@
+package com.jme3.shadow;
+
+/*
+ * Copyright (c) 2009-2012 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import com.jme3.asset.AssetManager;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import com.jme3.export.Savable;
+import com.jme3.material.Material;
+import com.jme3.material.RenderState;
+import com.jme3.math.ColorRGBA;
+import com.jme3.math.Matrix4f;
+import com.jme3.math.Vector2f;
+import com.jme3.math.Vector3f;
+import com.jme3.post.SceneProcessor;
+import com.jme3.renderer.Camera;
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.Renderer;
+import com.jme3.renderer.ViewPort;
+import com.jme3.renderer.queue.GeometryList;
+import com.jme3.renderer.queue.OpaqueComparator;
+import com.jme3.renderer.queue.RenderQueue;
+import com.jme3.renderer.queue.RenderQueue.ShadowMode;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.debug.WireFrustum;
+import com.jme3.shadow.CompareMode;
+import com.jme3.shadow.EdgeFilteringMode;
+import com.jme3.texture.FrameBuffer;
+import com.jme3.texture.Image.Format;
+import com.jme3.texture.Texture.MagFilter;
+import com.jme3.texture.Texture.MinFilter;
+import com.jme3.texture.Texture.ShadowCompareMode;
+import com.jme3.texture.Texture2D;
+import com.jme3.ui.Picture;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Abstract shadow renderer that holds commons feature to have for a shadow
+ * renderer.
+ *
+ * @author Rémy Bouquet aka Nehon
+ * @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 abstract class AbstractShadowRendererVR implements SceneProcessor, Savable {
+
+    protected int nbShadowMaps = 1;
+    protected float shadowMapSize;
+    protected float shadowIntensity = 0.7f;
+    protected RenderManager renderManager;
+    protected ViewPort viewPort;
+    protected FrameBuffer[] shadowFB;
+    protected Texture2D[] shadowMaps;
+    protected Texture2D dummyTex;
+    protected Material preshadowMat;
+    protected Material postshadowMat;
+    protected Matrix4f[] lightViewProjectionsMatrices;
+    protected AssetManager assetManager;
+    protected boolean debug = false;
+    protected float edgesThickness = 1.0f;
+    protected EdgeFilteringMode edgeFilteringMode = EdgeFilteringMode.Bilinear;
+    protected CompareMode shadowCompareMode = CompareMode.Hardware;
+    protected Picture[] dispPic;
+    protected RenderState forcedRenderState = new RenderState();
+    protected Boolean renderBackFacesShadows;
+
+    /**
+     * true if the fallback material should be used, otherwise false
+     */
+    protected boolean needsfallBackMaterial = false;
+    /**
+     * name of the post material technique
+     */
+    protected String postTechniqueName = "PostShadow";
+    /**
+     * list of materials for post shadow queue geometries
+     */
+    protected List<Material> matCache = new ArrayList<Material>();
+    protected GeometryList lightReceivers = new GeometryList(new OpaqueComparator());
+    protected GeometryList shadowMapOccluders = new GeometryList(new OpaqueComparator());
+    private String[] shadowMapStringCache;
+    private String[] lightViewStringCache;
+    /**
+     * fade shadows at distance
+     */
+    protected float zFarOverride = 0;
+    protected Vector2f fadeInfo;
+    protected float fadeLength;
+    protected Camera frustumCam;
+    /**
+     * true to skip the post pass when there are no shadow casters
+     */
+    protected boolean skipPostPass;
+    
+    /**
+     * used for serialization
+     */
+    protected AbstractShadowRendererVR(){        
+    }    
+    
+    /**
+     * Create an abstract shadow renderer. Subclasses invoke this constructor.
+     *
+     * @param assetManager the application asset manager
+     * @param shadowMapSize the size of the rendered shadow maps (512,1024,2048,
+     * etc...)
+     * @param nbShadowMaps the number of shadow maps rendered (the more shadow
+     * maps the more quality, the fewer fps).
+     */
+    protected AbstractShadowRendererVR(AssetManager assetManager, int shadowMapSize, int nbShadowMaps) {
+
+        this.assetManager = assetManager;
+        this.nbShadowMaps = nbShadowMaps;
+        this.shadowMapSize = shadowMapSize;
+        init(assetManager, nbShadowMaps, shadowMapSize);
+
+    }
+
+    private void init(AssetManager assetManager, int nbShadowMaps, int shadowMapSize) {
+        this.postshadowMat = new Material(assetManager, "Common/MatDefs/Shadow/PostShadow.j3md");
+        shadowFB = new FrameBuffer[nbShadowMaps];
+        shadowMaps = new Texture2D[nbShadowMaps];
+        dispPic = new Picture[nbShadowMaps];
+        lightViewProjectionsMatrices = new Matrix4f[nbShadowMaps];
+        shadowMapStringCache = new String[nbShadowMaps];
+        lightViewStringCache = new String[nbShadowMaps];
+
+        //DO NOT COMMENT THIS (it prevent the OSX incomplete read buffer crash)
+        dummyTex = new Texture2D(shadowMapSize, shadowMapSize, Format.RGBA8);
+
+        preshadowMat = new Material(assetManager, "Common/MatDefs/Shadow/PreShadow.j3md");
+        postshadowMat.setFloat("ShadowMapSize", shadowMapSize);
+
+        for (int i = 0; i < nbShadowMaps; i++) {
+            lightViewProjectionsMatrices[i] = new Matrix4f();
+            shadowFB[i] = new FrameBuffer(shadowMapSize, shadowMapSize, 1);
+            shadowMaps[i] = new Texture2D(shadowMapSize, shadowMapSize, Format.Depth);
+
+            shadowFB[i].setDepthTexture(shadowMaps[i]);
+
+            //DO NOT COMMENT THIS (it prevent the OSX incomplete read buffer crash)
+            shadowFB[i].setColorTexture(dummyTex);
+            shadowMapStringCache[i] = "ShadowMap" + i; 
+            lightViewStringCache[i] = "LightViewProjectionMatrix" + i;
+
+            postshadowMat.setTexture(shadowMapStringCache[i], shadowMaps[i]);
+
+            //quads for debuging purpose
+            dispPic[i] = new Picture("Picture" + i);
+            dispPic[i].setTexture(assetManager, shadowMaps[i], false);
+        }
+
+        setShadowCompareMode(shadowCompareMode);
+        setEdgeFilteringMode(edgeFilteringMode);
+        setShadowIntensity(shadowIntensity);
+        initForcedRenderState();
+    }
+
+    protected void initForcedRenderState() {
+        forcedRenderState.setFaceCullMode(RenderState.FaceCullMode.Front);
+        forcedRenderState.setColorWrite(false);
+        forcedRenderState.setDepthWrite(true);
+        forcedRenderState.setDepthTest(true);
+    }
+
+    /**
+     * set the post shadow material for this renderer
+     *
+     * @param postShadowMat
+     */
+    protected final void setPostShadowMaterial(Material postShadowMat) {
+        this.postshadowMat = postShadowMat;
+        postshadowMat.setFloat("ShadowMapSize", shadowMapSize);
+        for (int i = 0; i < nbShadowMaps; i++) {
+            postshadowMat.setTexture(shadowMapStringCache[i], shadowMaps[i]);
+        }
+        setShadowCompareMode(shadowCompareMode);
+        setEdgeFilteringMode(edgeFilteringMode);
+        setShadowIntensity(shadowIntensity);
+    }
+
+    /**
+     * Sets the filtering mode for shadow edges. See {@link EdgeFilteringMode}
+     * for more info.
+     *
+     * @param filterMode the desired filter mode (not null)
+     */
+    final public void setEdgeFilteringMode(EdgeFilteringMode filterMode) {
+        if (filterMode == null) {
+            throw new NullPointerException();
+        }
+
+        this.edgeFilteringMode = filterMode;
+        postshadowMat.setInt("FilterMode", filterMode.getMaterialParamValue());
+        postshadowMat.setFloat("PCFEdge", edgesThickness);
+        if (shadowCompareMode == CompareMode.Hardware) {
+            for (Texture2D shadowMap : shadowMaps) {
+                if (filterMode == EdgeFilteringMode.Bilinear) {
+                    shadowMap.setMagFilter(MagFilter.Bilinear);
+                    shadowMap.setMinFilter(MinFilter.BilinearNoMipMaps);
+                } else {
+                    shadowMap.setMagFilter(MagFilter.Nearest);
+                    shadowMap.setMinFilter(MinFilter.NearestNoMipMaps);
+                }
+            }
+        }
+    }
+
+    /**
+     * Get the edge filtering mode.
+     * @return the edge filtering mode.
+     */
+    public EdgeFilteringMode getEdgeFilteringMode() {
+        return edgeFilteringMode;
+    }
+
+    /**
+     * Sets the shadow compare mode. See {@link CompareMode} for more info.
+     *
+     * @param compareMode the desired compare mode (not null)
+     */
+    final public void setShadowCompareMode(CompareMode compareMode) {
+        if (compareMode == null) {
+            throw new IllegalArgumentException("Shadow compare mode cannot be null");
+        }
+
+        this.shadowCompareMode = compareMode;
+        for (Texture2D shadowMap : shadowMaps) {
+            if (compareMode == CompareMode.Hardware) {
+                shadowMap.setShadowCompareMode(ShadowCompareMode.LessOrEqual);
+                if (edgeFilteringMode == EdgeFilteringMode.Bilinear) {
+                    shadowMap.setMagFilter(MagFilter.Bilinear);
+                    shadowMap.setMinFilter(MinFilter.BilinearNoMipMaps);
+                } else {
+                    shadowMap.setMagFilter(MagFilter.Nearest);
+                    shadowMap.setMinFilter(MinFilter.NearestNoMipMaps);
+                }
+            } else {
+                shadowMap.setShadowCompareMode(ShadowCompareMode.Off);
+                shadowMap.setMagFilter(MagFilter.Nearest);
+                shadowMap.setMinFilter(MinFilter.NearestNoMipMaps);
+            }
+        }
+        postshadowMat.setBoolean("HardwareShadows", compareMode == CompareMode.Hardware);
+    }
+
+    /**
+     * returns the shadow compare mode
+     *
+     * @see CompareMode
+     * @return the shadowCompareMode
+     */
+    public CompareMode getShadowCompareMode() {
+        return shadowCompareMode;
+    }
+
+    /**
+     * debug function to create a visible frustum
+     */
+    protected Geometry createFrustum(Vector3f[] pts, int i) {
+        WireFrustum frustum = new WireFrustum(pts);
+        Geometry frustumMdl = new Geometry("f", frustum);
+        frustumMdl.setCullHint(Spatial.CullHint.Never);
+        frustumMdl.setShadowMode(ShadowMode.Off);
+        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
+        mat.getAdditionalRenderState().setWireframe(true);
+        frustumMdl.setMaterial(mat);
+        switch (i) {
+            case 0:
+                frustumMdl.getMaterial().setColor("Color", ColorRGBA.Pink);
+                break;
+            case 1:
+                frustumMdl.getMaterial().setColor("Color", ColorRGBA.Red);
+                break;
+            case 2:
+                frustumMdl.getMaterial().setColor("Color", ColorRGBA.Green);
+                break;
+            case 3:
+                frustumMdl.getMaterial().setColor("Color", ColorRGBA.Blue);
+                break;
+            default:
+                frustumMdl.getMaterial().setColor("Color", ColorRGBA.White);
+                break;
+        }
+
+        frustumMdl.updateGeometricState();
+        return frustumMdl;
+    }
+
+    /**
+     * Initialize this shadow renderer prior to its first update.
+     *
+     * @param rm the render manager
+     * @param vp the viewport
+     */
+    public void initialize(RenderManager rm, ViewPort vp) {
+        renderManager = rm;
+        viewPort = vp;
+        postTechniqueName = "PostShadow";
+        if(zFarOverride>0 && frustumCam == null){
+            initFrustumCam();
+        }
+    }
+    
+    /**
+     * delegates the initialization of the frustum cam to child renderers
+     */
+    protected abstract void initFrustumCam();
+
+    /**
+     * Test whether this shadow renderer has been initialized.
+     *
+     * @return true if initialized, otherwise false
+     */
+    public boolean isInitialized() {
+        return viewPort != null;
+    }
+
+    /**
+     * Invoked once per frame to update the shadow cams according to the light
+     * view.
+     * 
+     * @param viewCam the scene cam
+     */
+    protected abstract void updateShadowCams(Camera viewCam);
+
+    /**
+     * Returns a subclass-specific geometryList containing the occluders to be
+     * rendered in the shadow map
+     *
+     * @param shadowMapIndex the index of the shadow map being rendered
+     * @param shadowMapOccluders the list of occluders
+     * @return
+     */
+    protected abstract GeometryList getOccludersToRender(int shadowMapIndex, GeometryList shadowMapOccluders);
+
+    /**
+     * return the shadow camera to use for rendering the shadow map according
+     * the given index
+     *
+     * @param shadowMapIndex the index of the shadow map being rendered
+     * @return the shadowCam
+     */
+    protected abstract Camera getShadowCam(int shadowMapIndex);
+
+    /**
+     * responsible for displaying the frustum of the shadow cam for debug
+     * purpose
+     *
+     * @param shadowMapIndex
+     */
+    protected void doDisplayFrustumDebug(int shadowMapIndex) {
+    }
+
+    @SuppressWarnings("fallthrough")
+    public void postQueue(RenderQueue rq) {
+        lightReceivers.clear();
+        skipPostPass = false;
+        if ( !checkCulling(viewPort.getCamera()) ) {
+            skipPostPass = true;
+            return;
+        }
+
+        updateShadowCams(viewPort.getCamera());
+        
+        Renderer r = renderManager.getRenderer();
+        renderManager.setForcedMaterial(preshadowMat);
+        renderManager.setForcedTechnique("PreShadow");
+
+        for (int shadowMapIndex = 0; shadowMapIndex < nbShadowMaps; shadowMapIndex++) {
+
+                if (debugfrustums) {
+                    doDisplayFrustumDebug(shadowMapIndex);
+                }
+                renderShadowMap(shadowMapIndex);
+
+            }
+
+        debugfrustums = false;
+
+        //restore setting for future rendering
+        r.setFrameBuffer(viewPort.getOutputFrameBuffer());
+        renderManager.setForcedMaterial(null);
+        renderManager.setForcedTechnique(null);
+        renderManager.setCamera(viewPort.getCamera(), false);
+        
+    }
+
+    protected void renderShadowMap(int shadowMapIndex) {
+        shadowMapOccluders = getOccludersToRender(shadowMapIndex, shadowMapOccluders);
+        Camera shadowCam = getShadowCam(shadowMapIndex);
+
+        //saving light view projection matrix for this split            
+        lightViewProjectionsMatrices[shadowMapIndex].set(shadowCam.getViewProjectionMatrix());
+        renderManager.setCamera(shadowCam, false);
+
+        renderManager.getRenderer().setFrameBuffer(shadowFB[shadowMapIndex]);
+        renderManager.getRenderer().clearBuffers(true, true, true);
+        renderManager.setForcedRenderState(forcedRenderState);
+
+        // render shadow casters to shadow map
+        viewPort.getQueue().renderShadowQueue(shadowMapOccluders, renderManager, shadowCam, true);
+        renderManager.setForcedRenderState(null);
+    }
+    boolean debugfrustums = false;
+
+    /**
+     * Force the frustum to be displayed.
+     */
+    public void displayFrustum() {
+        debugfrustums = true;
+    }
+
+    /**
+     * For debugging purposes, display depth shadow maps.
+     */
+    protected void displayShadowMap(Renderer r) {
+        Camera cam = viewPort.getCamera();
+        renderManager.setCamera(cam, true);
+        int h = cam.getHeight();
+        for (int i = 0; i < dispPic.length; i++) {
+            dispPic[i].setPosition((128 * i) + (150 + 64 * (i + 1)), h / 20f);
+            dispPic[i].setWidth(128);
+            dispPic[i].setHeight(128);
+            dispPic[i].updateGeometricState();
+            renderManager.renderGeometry(dispPic[i]);
+        }
+        renderManager.setCamera(cam, false);
+    }
+
+    /**
+     * For debugging purposes, "snapshot" the current frustum to the scene.
+     */
+    public void displayDebug() {
+        debug = true;
+    }
+
+    protected abstract void getReceivers(GeometryList lightReceivers);
+
+    public void postFrame(FrameBuffer out) {
+        if (skipPostPass) {
+            return;
+        }
+        if (debug) {
+            displayShadowMap(renderManager.getRenderer());
+        }
+        
+        getReceivers(lightReceivers);
+
+        if (lightReceivers.size() != 0) {
+            //setting params to recieving geometry list
+            setMatParams(lightReceivers);
+
+            Camera cam = viewPort.getCamera();
+            //some materials in the scene does not have a post shadow technique so we're using the fall back material
+            if (needsfallBackMaterial) {
+                renderManager.setForcedMaterial(postshadowMat);
+            }
+
+            //forcing the post shadow technique and render state
+            renderManager.setForcedTechnique(postTechniqueName);
+
+            //rendering the post shadow pass
+            viewPort.getQueue().renderShadowQueue(lightReceivers, renderManager, cam, false);
+
+            //resetting renderManager settings
+            renderManager.setForcedTechnique(null);
+            renderManager.setForcedMaterial(null);
+            renderManager.setCamera(cam, false);
+            
+            //clearing the params in case there are some other shadow renderers
+            clearMatParams();
+        }
+    }
+    
+    /**
+     * This method is called once per frame and is responsible for clearing any
+     * material parameters that subclasses may need to clear on the post material.
+     *
+     * @param material the material that was used for the post shadow pass     
+     */
+    protected abstract void clearMaterialParameters(Material material);    
+    
+    private void clearMatParams(){
+        for (Material mat : matCache) {
+         
+            //clearing only necessary params, the others may be set by other 
+            //renderers 
+            //Note that j start at 1 because other shadow renderers will have 
+            //at least 1 shadow map and will set it on each frame anyway.
+            for (int j = 1; j < nbShadowMaps; j++) {
+                mat.clearParam(lightViewStringCache[j]);
+            }
+            for (int j = 1; j < nbShadowMaps; j++) {
+                mat.clearParam(shadowMapStringCache[j]);
+            }
+            mat.clearParam("FadeInfo");
+            clearMaterialParameters(mat);
+        }        
+        //No need to clear the postShadowMat params as the instance is locale to each renderer       
+    }
+
+    /**
+     * This method is called once per frame and is responsible for setting any
+     * material parameters that subclasses may need to set on the post material.
+     *
+     * @param material the material to use for the post shadow pass
+     */
+    protected abstract void setMaterialParameters(Material material);
+
+    private void setMatParams(GeometryList l) {
+        //iteration throught all the geometries of the list to gather the materials
+
+        buildMatCache(l);
+
+        //iterating through the mat cache and setting the parameters
+        for (Material mat : matCache) {
+
+            mat.setFloat("ShadowMapSize", shadowMapSize);
+
+            for (int j = 0; j < nbShadowMaps; j++) {
+                mat.setMatrix4(lightViewStringCache[j], lightViewProjectionsMatrices[j]);
+            }
+            for (int j = 0; j < nbShadowMaps; j++) {
+                mat.setTexture(shadowMapStringCache[j], shadowMaps[j]);
+            }
+            mat.setBoolean("HardwareShadows", shadowCompareMode == CompareMode.Hardware);
+            mat.setInt("FilterMode", edgeFilteringMode.getMaterialParamValue());
+            mat.setFloat("PCFEdge", edgesThickness);
+            mat.setFloat("ShadowIntensity", shadowIntensity);
+            if (fadeInfo != null) {
+               mat.setVector2("FadeInfo", fadeInfo);
+            }
+            if(renderBackFacesShadows != null){
+                mat.setBoolean("BackfaceShadows", renderBackFacesShadows);
+            }
+
+            setMaterialParameters(mat);
+        }
+
+        //At least one material of the receiving geoms does not support the post shadow techniques
+        //so we fall back to the forced material solution (transparent shadows won't be supported for these objects)
+        if (needsfallBackMaterial) {
+            setPostShadowParams();
+        }
+
+    }
+
+    private void buildMatCache(GeometryList l) {
+        matCache.clear();
+        for (int i = 0; i < l.size(); i++) {
+            Material mat = l.get(i).getMaterial();
+            //checking if the material has the post technique and adding it to the material cache
+            if (mat.getMaterialDef().getTechniqueDefs(postTechniqueName) != null) {
+                if (!matCache.contains(mat)) {
+                    matCache.add(mat);
+                }
+            } else {
+                needsfallBackMaterial = true;
+            }
+        }
+    }
+
+    /**
+     * for internal use only
+     */
+    protected void setPostShadowParams() {
+        setMaterialParameters(postshadowMat);
+        for (int j = 0; j < nbShadowMaps; j++) {
+            postshadowMat.setMatrix4(lightViewStringCache[j], lightViewProjectionsMatrices[j]);
+            postshadowMat.setTexture(shadowMapStringCache[j], shadowMaps[j]);
+        }
+        if (fadeInfo != null) {
+            postshadowMat.setVector2("FadeInfo", fadeInfo);
+        }
+        if(renderBackFacesShadows != null){
+            postshadowMat.setBoolean("BackfaceShadows", renderBackFacesShadows);
+        }
+    }
+    
+    /**
+     * How far the shadows are rendered in the view
+     *
+     * @see #setShadowZExtend(float zFar)
+     * @return shadowZExtend
+     */
+    public float getShadowZExtend() {
+        return zFarOverride;
+    }
+
+    /**
+     * Set the distance from the eye where the shadows will be rendered default
+     * value is dynamically computed to the shadow casters/receivers union bound
+     * zFar, capped to view frustum far value.
+     *
+     * @param zFar the zFar values that override the computed one
+     */
+    public void setShadowZExtend(float zFar) {
+        this.zFarOverride = zFar;        
+        if(zFarOverride == 0){
+            fadeInfo = null;
+            frustumCam = null;
+        }else{
+            if (fadeInfo != null) {
+                fadeInfo.set(zFarOverride - fadeLength, 1f / fadeLength);
+            }
+            if(frustumCam == null && viewPort != null){
+                initFrustumCam();
+            }
+        }
+    }
+    
+    /**
+     * Define the length over which the shadow will fade out when using a
+     * shadowZextend This is useful to make dynamic shadows fade into baked
+     * shadows in the distance.
+     *
+     * @param length the fade length in world units
+     */
+    public void setShadowZFadeLength(float length) {
+        if (length == 0) {
+            fadeInfo = null;
+            fadeLength = 0;
+            postshadowMat.clearParam("FadeInfo");
+        } else {
+            if (zFarOverride == 0) {
+                fadeInfo = new Vector2f(0, 0);
+            } else {
+                fadeInfo = new Vector2f(zFarOverride - length, 1.0f / length);
+            }
+            fadeLength = length;
+            postshadowMat.setVector2("FadeInfo", fadeInfo);
+        }
+    }
+
+    /**
+     * get the length over which the shadow will fade out when using a
+     * shadowZextend
+     *
+     * @return the fade length in world units
+     */
+    public float getShadowZFadeLength() {
+        if (fadeInfo != null) {
+            return zFarOverride - fadeInfo.x;
+        }
+        return 0f;
+    }
+    
+    /**
+     * returns true if the light source bounding box is in the view frustum
+     * @return 
+     */
+    protected abstract boolean checkCulling(Camera viewCam);
+    
+    public void preFrame(float tpf) {           
+    }
+
+    public void cleanup() {
+    }
+
+    public void reshape(ViewPort vp, int w, int h) {
+    }
+
+    /**
+     * Returns the shadow intensity.
+     *
+     * @see #setShadowIntensity(float shadowIntensity)
+     * @return shadowIntensity
+     */
+    public float getShadowIntensity() {
+        return shadowIntensity;
+    }
+
+    /**
+     * Set the shadowIntensity. The value should be between 0 and 1. A 0 value
+     * gives a bright and invisible shadow, a 1 value gives a pitch black
+     * shadow. The default is 0.7
+     *
+     * @param shadowIntensity the darkness of the shadow
+     */
+    final public void setShadowIntensity(float shadowIntensity) {
+        this.shadowIntensity = shadowIntensity;
+        postshadowMat.setFloat("ShadowIntensity", shadowIntensity);
+    }
+
+    /**
+     * returns the edges thickness
+     *
+     * @see #setEdgesThickness(int edgesThickness)
+     * @return edgesThickness
+     */
+    public int getEdgesThickness() {
+        return (int) (edgesThickness * 10);
+    }
+
+    /**
+     * Sets the shadow edges thickness. default is 1, setting it to lower values
+     * can help to reduce the jagged effect of the shadow edges
+     * @param edgesThickness the shadow edges thickness.
+     */
+    public void setEdgesThickness(int edgesThickness) {
+        this.edgesThickness = Math.max(1, Math.min(edgesThickness, 10));
+        this.edgesThickness *= 0.1f;
+        postshadowMat.setFloat("PCFEdge", edgesThickness);
+    }
+
+    /**
+     * This method does nothing now and is kept only for backward compatibility.
+     * @return <code>false</code>
+     * @deprecated This method does nothing now and is kept only for backward compatibility.
+     */
+    @Deprecated
+    public boolean isFlushQueues() { return false; }
+
+    /**
+     * This method does nothing now and is kept only for backward compatibility.
+     * @param flushQueues any boolean.
+     * @deprecated This method does nothing now and is kept only for backward compatibility.
+     */
+    @Deprecated
+    public void setFlushQueues(boolean flushQueues) {}
+
+
+    /**
+     * Returns the pre shadows pass render state.
+     * use it to adjust the RenderState parameters of the pre shadow pass.
+     * Note that this will be overridden if the preShadow technique in the material has a ForcedRenderState
+     * @return the pre shadow render state.
+     */
+    public RenderState getPreShadowForcedRenderState() {
+        return forcedRenderState;
+    }
+
+    /**
+     * Set to true if you want back faces shadows on geometries.
+     * Note that back faces shadows will be blended over dark lighten areas and may produce overly dark lighting.
+     *
+     * Also note that setting this parameter will override this parameter for ALL materials in the scene.
+     * You can alternatively change this parameter on a single material using {@link Material#setBoolean(String, boolean)}
+     *
+     * This also will automatically adjust the faceCullMode and the PolyOffset of the pre shadow pass.
+     * You can modify them by using {@link #getPreShadowForcedRenderState()}
+     *
+     * @param renderBackFacesShadows true or false.
+     */
+    public void setRenderBackFacesShadows(Boolean renderBackFacesShadows) {
+        this.renderBackFacesShadows = renderBackFacesShadows;
+        if(renderBackFacesShadows) {
+            getPreShadowForcedRenderState().setPolyOffset(5, 3);
+            getPreShadowForcedRenderState().setFaceCullMode(RenderState.FaceCullMode.Back);
+        }else{
+            getPreShadowForcedRenderState().setPolyOffset(0, 0);
+            getPreShadowForcedRenderState().setFaceCullMode(RenderState.FaceCullMode.Front);
+        }
+    }
+
+    /**
+     * if this processor renders back faces shadows
+     * @return true if this processor renders back faces shadows
+     */
+    public boolean isRenderBackFacesShadows() {
+        return renderBackFacesShadows != null?renderBackFacesShadows:false;
+    }
+
+    /**
+     * De-serialize this instance, for example when loading from a J3O file.
+     *
+     * @param im importer (not null)
+     */
+    public void read(JmeImporter im) throws IOException {
+        InputCapsule ic = (InputCapsule) im.getCapsule(this);
+        assetManager = im.getAssetManager();
+        nbShadowMaps = ic.readInt("nbShadowMaps", 1);
+        shadowMapSize = ic.readFloat("shadowMapSize", 0f);
+        shadowIntensity = ic.readFloat("shadowIntensity", 0.7f);
+        edgeFilteringMode = ic.readEnum("edgeFilteringMode", EdgeFilteringMode.class, EdgeFilteringMode.Bilinear);
+        shadowCompareMode = ic.readEnum("shadowCompareMode", CompareMode.class, CompareMode.Hardware);
+        init(assetManager, nbShadowMaps, (int) shadowMapSize);
+        edgesThickness = ic.readFloat("edgesThickness", 1.0f);
+        postshadowMat.setFloat("PCFEdge", edgesThickness);
+
+    }
+
+    /**
+     * Serialize this instance, for example when saving to a J3O file.
+     *
+     * @param ex exporter (not null)
+     */
+    public void write(JmeExporter ex) throws IOException {
+        OutputCapsule oc = (OutputCapsule) ex.getCapsule(this);
+        oc.write(nbShadowMaps, "nbShadowMaps", 1);
+        oc.write(shadowMapSize, "shadowMapSize", 0);
+        oc.write(shadowIntensity, "shadowIntensity", 0.7f);
+        oc.write(edgeFilteringMode, "edgeFilteringMode", EdgeFilteringMode.Bilinear);
+        oc.write(shadowCompareMode, "shadowCompareMode", CompareMode.Hardware);
+        oc.write(edgesThickness, "edgesThickness", 1.0f);
+    }
+}

+ 167 - 0
jme3-vr/src/main/java/com/jme3/shadow/DirectionalLightShadowFilterVR.java

@@ -0,0 +1,167 @@
+package com.jme3.shadow;
+
+/*
+ * Copyright (c) 2009-2012 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import com.jme3.asset.AssetManager;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import com.jme3.light.DirectionalLight;
+import java.io.IOException;
+
+/**
+ *
+ * This Filter does basically the same as a DirectionalLightShadowRenderer
+ * except it renders the post shadow pass as a fulscreen quad pass instead of a
+ * geometry pass. It's mostly faster than PssmShadowRenderer as long as you have
+ * more than a about ten shadow recieving objects. The expense is the draw back
+ * that the shadow Recieve mode set on spatial is ignored. So basically all and
+ * only objects that render depth in the scene receive shadows. See this post
+ * for more details
+ * http://jmonkeyengine.org/groups/general-2/forum/topic/silly-question-about-shadow-rendering/#post-191599
+ *
+ * API is basically the same as the PssmShadowRenderer;
+ *
+ * @author Rémy Bouquet aka Nehon
+ * @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 DirectionalLightShadowFilterVR extends AbstractShadowFilterVR<DirectionalLightShadowRendererVR> {
+
+    /**
+     * Creates a DirectionalLightShadowFilter Shadow Filter More info on the
+     * technique at <a
+     * href="http://http.developer.nvidia.com/GPUGems3/gpugems3_ch10.html">http://http.developer.nvidia.com/GPUGems3/gpugems3_ch10.html</a>
+     *
+     * @param assetManager the application asset manager
+     * @param shadowMapSize the size of the rendered shadowmaps (512,1024,2048,
+     * etc...)
+     * @param nbSplits the number of shadow maps rendered (the more shadow maps
+     * the more quality, the less fps).
+     */
+    public DirectionalLightShadowFilterVR(AssetManager assetManager, int shadowMapSize, int nbSplits) {
+        super(assetManager, shadowMapSize, new DirectionalLightShadowRendererVR(assetManager, shadowMapSize, nbSplits));
+    }
+
+    /**
+     * Creates a DirectionalLightShadowFilter Shadow Filter More info on the
+     * technique at <a
+     * href="http://http.developer.nvidia.com/GPUGems3/gpugems3_ch10.html">http://http.developer.nvidia.com/GPUGems3/gpugems3_ch10.html</a>.
+     * @param assetManager the application asset manager
+     * @param shadowMapSize the size of the rendered shadowmaps (512, 1024, 2048, etc...)
+     * @param nbSplits the number of shadow maps rendered (the more shadow maps the more quality, the less fps).
+     * @param useMatDef the material to attach to this filter.
+     */
+    public DirectionalLightShadowFilterVR(AssetManager assetManager, int shadowMapSize, int nbSplits, String useMatDef) {
+        super(assetManager, shadowMapSize, new DirectionalLightShadowRendererVR(assetManager, shadowMapSize, nbSplits), useMatDef);
+    }
+    
+    /**
+     * return the light used to cast shadows
+     *
+     * @return the DirectionalLight
+     */
+    public DirectionalLight getLight() {
+        return shadowRenderer.getLight();
+    }
+
+    /**
+     * Sets the light to use to cast shadows
+     *
+     * @param light a DirectionalLight
+     */
+    public void setLight(DirectionalLight light) {
+        shadowRenderer.setLight(light);
+    }
+
+    /**
+     * returns the labda parameter
+     *
+     * @see #setLambda(float lambda)
+     * @return lambda
+     */
+    public float getLambda() {
+        return shadowRenderer.getLambda();
+    }
+
+    /**
+     * Adjust the repartition of the different shadow maps in the shadow extend
+     * usualy goes from 0.0 to 1.0 a low value give a more linear repartition
+     * resulting in a constant quality in the shadow over the extends, but near
+     * shadows could look very jagged a high value give a more logarithmic
+     * repartition resulting in a high quality for near shadows, but the quality
+     * quickly decrease over the extend. the default value is set to 0.65f
+     * (theoric optimal value).
+     *
+     * @param lambda the lambda value.
+     */
+    public void setLambda(float lambda) {
+        shadowRenderer.setLambda(lambda);
+    }
+
+    /**
+     * Check if stabilization is enabled.
+     * @return <code>true</code> if the stabilization is enabled and <code>false</code> otherwise.
+     * @see #setEnabledStabilization(boolean)
+     */
+    public boolean isEnabledStabilization() {
+        return shadowRenderer.isEnabledStabilization();
+    }
+    
+    /**
+     * Enables the stabilization of the shadows's edges. (default is <code>true</code>)
+     * This prevents shadows' edges to flicker when the camera moves
+     * However it can lead to some shadow quality loss in some particular scenes.
+     * @param stabilize <code>true</code> if the stabilization has to be enabled and <code>false</code> otherwise.
+     * @see #isEnabledStabilization()
+     */
+    public void setEnabledStabilization(boolean stabilize) {
+        shadowRenderer.setEnabledStabilization(stabilize);        
+    }    
+
+    @Override
+    public void write(JmeExporter ex) throws IOException {
+        super.write(ex);
+        OutputCapsule oc = ex.getCapsule(this);
+        oc.write(shadowRenderer, "shadowRenderer", null);
+
+    }
+
+    @Override
+    public void read(JmeImporter im) throws IOException {
+        super.read(im);
+        InputCapsule ic = im.getCapsule(this);
+        shadowRenderer = (DirectionalLightShadowRendererVR) ic.readSavable("shadowRenderer", null);
+    }
+}

+ 312 - 0
jme3-vr/src/main/java/com/jme3/shadow/DirectionalLightShadowRendererVR.java

@@ -0,0 +1,312 @@
+package com.jme3.shadow;
+
+/*
+ * Copyright (c) 2009-2012 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import com.jme3.asset.AssetManager;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import com.jme3.light.DirectionalLight;
+import com.jme3.material.Material;
+import com.jme3.math.ColorRGBA;
+import com.jme3.math.Vector2f;
+import com.jme3.math.Vector3f;
+import com.jme3.profile.AppProfiler;
+import com.jme3.renderer.Camera;
+import com.jme3.renderer.queue.GeometryList;
+import com.jme3.renderer.queue.RenderQueue;
+import com.jme3.scene.Node;
+import com.jme3.scene.Spatial;
+import com.jme3.shadow.PssmShadowUtil;
+import com.jme3.shadow.ShadowUtil;
+
+import java.io.IOException;
+
+/**
+ * DirectionalLightShadowRenderer renderer use Parrallel Split Shadow Mapping
+ * technique (pssm)<br> It splits the view frustum in several parts and compute
+ * a shadow map for each one.<br> splits are distributed so that the closer they
+ * are from the camera, the smaller they are to maximize the resolution used of
+ * the shadow map.<br> This result in a better quality shadow than standard
+ * shadow mapping.<br> for more informations on this read this <a
+ * href="http://http.developer.nvidia.com/GPUGems3/gpugems3_ch10.html">http://http.developer.nvidia.com/GPUGems3/gpugems3_ch10.html</a><br>
+ * <p/>
+ * @author Rémy Bouquet aka Nehon
+ * @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 DirectionalLightShadowRendererVR extends AbstractShadowRendererVR {
+
+    protected float lambda = 0.65f;    
+    protected Camera shadowCam;
+    protected ColorRGBA splits;
+    protected float[] splitsArray;
+    protected DirectionalLight light;
+    protected Vector3f[] points = new Vector3f[8];
+    //Holding the info for fading shadows in the far distance   
+    private boolean stabilize = true;
+
+    private AppProfiler profiler = null;
+    
+    /**
+     * Used for serialzation use
+     * DirectionalLightShadowRenderer#DirectionalLightShadowRenderer(AssetManager
+     * assetManager, int shadowMapSize, int nbSplits)
+     */
+    public DirectionalLightShadowRendererVR() {
+        super();
+    }
+
+    /**
+     * Create a DirectionalLightShadowRenderer More info on the technique at <a
+     * href="http://http.developer.nvidia.com/GPUGems3/gpugems3_ch10.html">http://http.developer.nvidia.com/GPUGems3/gpugems3_ch10.html</a>
+     *
+     * @param assetManager the application asset manager
+     * @param shadowMapSize the size of the rendered shadowmaps (512,1024,2048,
+     * etc...)
+     * @param nbSplits the number of shadow maps rendered (the more shadow maps
+     * the more quality, the less fps).
+     */
+    public DirectionalLightShadowRendererVR(AssetManager assetManager, int shadowMapSize, int nbSplits) {
+        super(assetManager, shadowMapSize, nbSplits);
+        init(nbSplits, shadowMapSize);
+    }
+
+    private void init(int nbSplits, int shadowMapSize) {
+        nbShadowMaps = Math.max(Math.min(nbSplits, 4), 1);
+        if (nbShadowMaps != nbSplits) {
+            throw new IllegalArgumentException("Number of splits must be between 1 and 4. Given value : " + nbSplits);
+        }
+        splits = new ColorRGBA();
+        splitsArray = new float[nbSplits + 1];
+        shadowCam = new Camera(shadowMapSize, shadowMapSize);
+        shadowCam.setParallelProjection(true);
+        for (int i = 0; i < points.length; i++) {
+            points[i] = new Vector3f();
+        }
+    }
+
+    @Override
+    protected void initFrustumCam() {
+        //nothing to do
+    }
+
+    /**
+     * return the light used to cast shadows
+     * @return the DirectionalLight
+     */
+    public DirectionalLight getLight() {
+        return light;
+    }
+
+    /**
+     * Sets the light to use to cast shadows
+     * @param light a DirectionalLight
+     */
+    public void setLight(DirectionalLight light) {
+        this.light = light;
+    }
+
+    @Override
+    protected void updateShadowCams(Camera viewCam) {
+
+        float zFar = zFarOverride;
+        if (zFar == 0) {
+            zFar = viewCam.getFrustumFar();
+        }
+
+        //We prevent computing the frustum points and splits with zeroed or negative near clip value
+        float frustumNear = Math.max(viewCam.getFrustumNear(), 0.001f);
+        ShadowUtil.updateFrustumPoints(viewCam, frustumNear, zFar, 1.0f, points);
+
+        //shadowCam.setDirection(direction);
+        shadowCam.getRotation().lookAt(light.getDirection(), shadowCam.getUp());
+        shadowCam.update();
+        shadowCam.updateViewProjection();
+
+        PssmShadowUtil.updateFrustumSplits(splitsArray, frustumNear, zFar, lambda);
+
+        // in parallel projection shadow position goe from 0 to 1
+        if(viewCam.isParallelProjection()){
+            for (int i = 0; i < nbShadowMaps; i++) {
+                splitsArray[i] = splitsArray[i]/(zFar- frustumNear);
+            }
+        }
+
+        switch (splitsArray.length) {
+            case 5:
+                splits.a = splitsArray[4];
+            case 4:
+                splits.b = splitsArray[3];
+            case 3:
+                splits.g = splitsArray[2];
+            case 2:
+            case 1:
+                splits.r = splitsArray[1];
+                break;
+        }
+
+    }
+    
+    @Override
+    protected GeometryList getOccludersToRender(int shadowMapIndex, GeometryList shadowMapOccluders) {
+
+        // update frustum points based on current camera and split
+        ShadowUtil.updateFrustumPoints(viewPort.getCamera(), splitsArray[shadowMapIndex], splitsArray[shadowMapIndex + 1], 1.0f, points);
+
+        //Updating shadow cam with curent split frustra
+        if (lightReceivers.size()==0) {
+            for (Spatial scene : viewPort.getScenes()) {
+              ShadowUtil.getGeometriesInCamFrustum(scene, viewPort.getCamera(), RenderQueue.ShadowMode.Receive, lightReceivers);
+            }
+        }
+        ShadowUtil.updateShadowCamera(viewPort, lightReceivers, shadowCam, points, shadowMapOccluders, stabilize?shadowMapSize:0);
+
+        return shadowMapOccluders;
+    }
+
+    @Override
+    protected void getReceivers(GeometryList lightReceivers) {
+        if (lightReceivers.size()==0) {
+            for (Spatial scene : viewPort.getScenes()) {
+                ShadowUtil.getGeometriesInCamFrustum(scene, viewPort.getCamera(), RenderQueue.ShadowMode.Receive, lightReceivers);
+            }
+        }
+    }
+
+    @Override
+    protected Camera getShadowCam(int shadowMapIndex) {
+        return shadowCam;
+    }
+
+    @Override
+    protected void doDisplayFrustumDebug(int shadowMapIndex) {
+        ((Node) viewPort.getScenes().get(0)).attachChild(createFrustum(points, shadowMapIndex));
+        ShadowUtil.updateFrustumPoints2(shadowCam, points);
+        ((Node) viewPort.getScenes().get(0)).attachChild(createFrustum(points, shadowMapIndex));
+    }
+
+    @Override
+    protected void setMaterialParameters(Material material) {
+        material.setColor("Splits", splits);
+        material.setVector3("LightDir", light.getDirection());
+        if (fadeInfo != null) {
+            material.setVector2("FadeInfo", fadeInfo);
+        }
+    }
+
+    @Override
+    protected void clearMaterialParameters(Material material) {
+        material.clearParam("Splits");
+        material.clearParam("FadeInfo");
+        material.clearParam("LightDir");
+    }
+
+    /**
+     * returns the labda parameter see #setLambda(float lambda)
+     *
+     * @return lambda
+     */
+    public float getLambda() {
+        return lambda;
+    }
+
+    /**
+     * Adjust the repartition of the different shadow maps in the shadow extend
+     * usualy goes from 0.0 to 1.0
+     * a low value give a more linear repartition resulting in a constant quality in the shadow over the extends, but near shadows could look very jagged
+     * a high value give a more logarithmic repartition resulting in a high quality for near shadows, but the quality quickly decrease over the extend.
+     * the default value is set to 0.65f (theoric optimal value).
+     * @param lambda the lambda value.
+     */
+    public void setLambda(float lambda) {
+        this.lambda = lambda;
+    }
+
+    /**
+     * Check if the stabilization is enabled.
+     * @return <code>true</code> if stabilization is enabled and <code>false</code> otherwise.
+     */
+    public boolean isEnabledStabilization() {
+        return stabilize;
+    }
+    
+    /**
+     * Enables the stabilization of the shadows's edges. (default is true)
+     * This prevents shadows' edges to flicker when the camera moves
+     * However it can lead to some shadow quality loss in some particular scenes.
+     * @param stabilize  <code>true</code> if stabilization has to be enabled and <code>false</code> otherwise.
+     */
+    public void setEnabledStabilization(boolean stabilize) {
+        this.stabilize = stabilize;
+    }
+    
+    @Override
+    public void read(JmeImporter im) throws IOException {
+        super.read(im);
+        InputCapsule ic = (InputCapsule) im.getCapsule(this);
+        lambda = ic.readFloat("lambda", 0.65f);
+        zFarOverride = ic.readInt("zFarOverride", 0);
+        light = (DirectionalLight) ic.readSavable("light", null);
+        fadeInfo = (Vector2f) ic.readSavable("fadeInfo", null);
+        fadeLength = ic.readFloat("fadeLength", 0f);
+        init(nbShadowMaps, (int) shadowMapSize);
+    }
+
+    @Override
+    public void write(JmeExporter ex) throws IOException {
+        super.write(ex);
+        OutputCapsule oc = (OutputCapsule) ex.getCapsule(this);
+        oc.write(lambda, "lambda", 0.65f);
+        oc.write(zFarOverride, "zFarOverride", 0);
+        oc.write(light, "light", null);
+        oc.write(fadeInfo, "fadeInfo", null);
+        oc.write(fadeLength, "fadeLength", 0f);
+    }
+
+    /**
+     * Directional light are always in the view frustum
+     * @param viewCam
+     * @return 
+     */
+    @Override
+    protected boolean checkCulling(Camera viewCam) {
+        return true;
+    }
+
+	@Override
+	public void setProfiler(AppProfiler profiler) {
+		this.profiler = profiler;
+	}
+}

+ 48 - 0
jme3-vr/src/main/java/com/jme3/shadow/InstancedDirectionalShadowFilter.java

@@ -0,0 +1,48 @@
+/*
+ * 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.shadow;
+
+import com.jme3.app.VRApplication;
+import com.jme3.math.Matrix4f;
+import com.jme3.math.Vector4f;
+import com.jme3.renderer.Camera;
+
+/**
+ * An instanced version of the {@link DirectionalLightShadowFilterVR directional light shadow filter}.
+ * @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 InstancedDirectionalShadowFilter extends DirectionalLightShadowFilterVR {    
+    
+    private final Vector4f temp4f = new Vector4f(), temp4f2 = new Vector4f();
+    
+    private VRApplication application;
+    
+    /**
+     * Create a new instanced version of the {@link DirectionalLightShadowFilterVR directional light shadow filter}.
+     * @param application the VR application that this filter is attached to.
+     * @param camera 
+     * @param shadowMapSize the size of the rendered shadowmaps (512, 1024, 2048, etc...)
+     * @param nbSplits the number of shadow maps rendered (the more shadow maps the more quality, the less fps).
+     * @param instancedRendering <code>true</code> if this filter has to use instance rendering and <code>false</code> otherwise.
+     */
+    public InstancedDirectionalShadowFilter(VRApplication application, Camera camera, int shadowMapSize, int nbSplits, boolean instancedRendering) {
+        super(application.getAssetManager(), shadowMapSize, nbSplits, "Common/MatDefs/VR/PostShadowFilter.j3md");
+    }        
+    
+    @Override    
+    protected void preFrame(float tpf) {
+        shadowRenderer.preFrame(tpf);
+        if( application.isInstanceVRRendering() ) {
+            material.setMatrix4("ViewProjectionMatrixInverseRight", application.getVRViewManager().getRightCamera().getViewProjectionMatrix().invert());
+            Matrix4f m = application.getVRViewManager().getRightCamera().getViewProjectionMatrix();
+            material.setVector4("ViewProjectionMatrixRow2Right", temp4f2.set(m.m20, m.m21, m.m22, m.m23));
+        }
+        material.setMatrix4("ViewProjectionMatrixInverse", viewPort.getCamera().getViewProjectionMatrix().invert());
+        Matrix4f m = viewPort.getCamera().getViewProjectionMatrix();
+        material.setVector4("ViewProjectionMatrixRow2", temp4f.set(m.m20, m.m21, m.m22, m.m23));
+    }
+}

+ 78 - 0
jme3-vr/src/main/java/com/jme3/shadow/VRDirectionalLightShadowRenderer.java

@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2009-2012 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.shadow;
+
+import com.jme3.asset.AssetManager;
+import com.jme3.shadow.DirectionalLightShadowRenderer;
+
+/**
+ * DirectionalLightShadowRenderer renderer use Parrallel Split Shadow Mapping
+ * technique (pssm)<br> It splits the view frustum in several parts and compute
+ * a shadow map for each one.<br> splits are distributed so that the closer they
+ * are from the camera, the smaller they are to maximize the resolution used of
+ * the shadow map.<br> This result in a better quality shadow than standard
+ * shadow mapping.<br> for more informations on this read this <a
+ * href="http://http.developer.nvidia.com/GPUGems3/gpugems3_ch10.html">http://http.developer.nvidia.com/GPUGems3/gpugems3_ch10.html</a><br>
+ * <p/>
+ * @author Rémy Bouquet aka Nehon
+ */
+public class VRDirectionalLightShadowRenderer extends DirectionalLightShadowRenderer {
+
+    /**
+     * Create a OculusDirectionalLightShadowRenderer More info on the technique at <a
+     * href="http://http.developer.nvidia.com/GPUGems3/gpugems3_ch10.html">http://http.developer.nvidia.com/GPUGems3/gpugems3_ch10.html</a>
+     *
+     * @param assetManager the application asset manager
+     * @param shadowMapSize the size of the rendered shadowmaps (512,1024,2048,
+     * etc...)
+     * @param nbSplits the number of shadow maps rendered (the more shadow maps
+     * the more quality, the less fps).
+     */
+    public VRDirectionalLightShadowRenderer(AssetManager assetManager, int shadowMapSize, int nbSplits) {
+        super(assetManager, shadowMapSize, nbSplits);
+    }
+    
+    @Override
+    public VRDirectionalLightShadowRenderer clone() {
+        VRDirectionalLightShadowRenderer clone = new VRDirectionalLightShadowRenderer(assetManager, (int)shadowMapSize, nbShadowMaps);
+        clone.setEdgeFilteringMode(getEdgeFilteringMode());
+        clone.setEdgesThickness(getEdgesThickness());
+        clone.setEnabledStabilization(isEnabledStabilization());
+        clone.setLambda(getLambda());
+        clone.setLight(getLight());
+        clone.setShadowCompareMode(getShadowCompareMode());
+        clone.setShadowIntensity(getShadowIntensity());
+        clone.setShadowZExtend(getShadowZExtend());
+        clone.setShadowZFadeLength(getShadowZFadeLength());
+        return clone;
+    }
+}

+ 49 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/AppOverrideKeys_t.java

@@ -0,0 +1,49 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1133</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class AppOverrideKeys_t extends Structure {
+	/**
+	 * const char *<br>
+	 * C type : char*
+	 */
+	public Pointer pchKey;
+	/**
+	 * const char *<br>
+	 * C type : char*
+	 */
+	public Pointer pchValue;
+	public AppOverrideKeys_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("pchKey", "pchValue");
+	}
+	/**
+	 * @param pchKey const char *<br>
+	 * C type : char*<br>
+	 * @param pchValue const char *<br>
+	 * C type : char*
+	 */
+	public AppOverrideKeys_t(Pointer pchKey, Pointer pchValue) {
+		super();
+		this.pchKey = pchKey;
+		this.pchValue = pchValue;
+	}
+	public AppOverrideKeys_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends AppOverrideKeys_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends AppOverrideKeys_t implements Structure.ByValue {
+		
+	};
+}

+ 89 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/COpenVRContext.java

@@ -0,0 +1,89 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import com.sun.jna.ptr.IntByReference;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1262</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class COpenVRContext extends Structure {
+	/**
+	 * class vr::IVRSystem *<br>
+	 * C type : intptr_t
+	 */
+	public IntByReference m_pVRSystem;
+	/**
+	 * class vr::IVRChaperone *<br>
+	 * C type : intptr_t
+	 */
+	public IntByReference m_pVRChaperone;
+	/**
+	 * class vr::IVRChaperoneSetup *<br>
+	 * C type : intptr_t
+	 */
+	public IntByReference m_pVRChaperoneSetup;
+	/**
+	 * class vr::IVRCompositor *<br>
+	 * C type : intptr_t
+	 */
+	public IntByReference m_pVRCompositor;
+	/**
+	 * class vr::IVROverlay *<br>
+	 * C type : intptr_t
+	 */
+	public IntByReference m_pVROverlay;
+	/**
+	 * class vr::IVRResources *<br>
+	 * C type : intptr_t
+	 */
+	public IntByReference m_pVRResources;
+	/**
+	 * class vr::IVRRenderModels *<br>
+	 * C type : intptr_t
+	 */
+	public IntByReference m_pVRRenderModels;
+	/**
+	 * class vr::IVRExtendedDisplay *<br>
+	 * C type : intptr_t
+	 */
+	public IntByReference m_pVRExtendedDisplay;
+	/**
+	 * class vr::IVRSettings *<br>
+	 * C type : intptr_t
+	 */
+	public IntByReference m_pVRSettings;
+	/**
+	 * class vr::IVRApplications *<br>
+	 * C type : intptr_t
+	 */
+	public IntByReference m_pVRApplications;
+	/**
+	 * class vr::IVRTrackedCamera *<br>
+	 * C type : intptr_t
+	 */
+	public IntByReference m_pVRTrackedCamera;
+	/**
+	 * class vr::IVRScreenshots *<br>
+	 * C type : intptr_t
+	 */
+	public IntByReference m_pVRScreenshots;
+	public COpenVRContext() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("m_pVRSystem", "m_pVRChaperone", "m_pVRChaperoneSetup", "m_pVRCompositor", "m_pVROverlay", "m_pVRResources", "m_pVRRenderModels", "m_pVRExtendedDisplay", "m_pVRSettings", "m_pVRApplications", "m_pVRTrackedCamera", "m_pVRScreenshots");
+	}
+	public COpenVRContext(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends COpenVRContext implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends COpenVRContext implements Structure.ByValue {
+		
+	};
+}

+ 53 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/CameraVideoStreamFrameHeader_t.java

@@ -0,0 +1,53 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1127</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class CameraVideoStreamFrameHeader_t extends Structure {
+	/**
+	 * @see EVRTrackedCameraFrameType<br>
+	 * C type : EVRTrackedCameraFrameType
+	 */
+	public int eFrameType;
+	public int nWidth;
+	public int nHeight;
+	public int nBytesPerPixel;
+	public int nFrameSequence;
+	/** C type : TrackedDevicePose_t */
+	public TrackedDevicePose_t standingTrackedDevicePose;
+	public CameraVideoStreamFrameHeader_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("eFrameType", "nWidth", "nHeight", "nBytesPerPixel", "nFrameSequence", "standingTrackedDevicePose");
+	}
+	/**
+	 * @param eFrameType @see EVRTrackedCameraFrameType<br>
+	 * C type : EVRTrackedCameraFrameType<br>
+	 * @param standingTrackedDevicePose C type : TrackedDevicePose_t
+	 */
+	public CameraVideoStreamFrameHeader_t(int eFrameType, int nWidth, int nHeight, int nBytesPerPixel, int nFrameSequence, TrackedDevicePose_t standingTrackedDevicePose) {
+		super();
+		this.eFrameType = eFrameType;
+		this.nWidth = nWidth;
+		this.nHeight = nHeight;
+		this.nBytesPerPixel = nBytesPerPixel;
+		this.nFrameSequence = nFrameSequence;
+		this.standingTrackedDevicePose = standingTrackedDevicePose;
+	}
+	public CameraVideoStreamFrameHeader_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends CameraVideoStreamFrameHeader_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends CameraVideoStreamFrameHeader_t implements Structure.ByValue {
+		
+	};
+}

+ 43 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/Compositor_CumulativeStats.java

@@ -0,0 +1,43 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1176</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class Compositor_CumulativeStats extends Structure {
+	public int m_nPid;
+	public int m_nNumFramePresents;
+	public int m_nNumDroppedFrames;
+	public int m_nNumReprojectedFrames;
+	public int m_nNumFramePresentsOnStartup;
+	public int m_nNumDroppedFramesOnStartup;
+	public int m_nNumReprojectedFramesOnStartup;
+	public int m_nNumLoading;
+	public int m_nNumFramePresentsLoading;
+	public int m_nNumDroppedFramesLoading;
+	public int m_nNumReprojectedFramesLoading;
+	public int m_nNumTimedOut;
+	public int m_nNumFramePresentsTimedOut;
+	public int m_nNumDroppedFramesTimedOut;
+	public int m_nNumReprojectedFramesTimedOut;
+	public Compositor_CumulativeStats() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("m_nPid", "m_nNumFramePresents", "m_nNumDroppedFrames", "m_nNumReprojectedFrames", "m_nNumFramePresentsOnStartup", "m_nNumDroppedFramesOnStartup", "m_nNumReprojectedFramesOnStartup", "m_nNumLoading", "m_nNumFramePresentsLoading", "m_nNumDroppedFramesLoading", "m_nNumReprojectedFramesLoading", "m_nNumTimedOut", "m_nNumFramePresentsTimedOut", "m_nNumDroppedFramesTimedOut", "m_nNumReprojectedFramesTimedOut");
+	}
+	public Compositor_CumulativeStats(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends Compositor_CumulativeStats implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends Compositor_CumulativeStats implements Structure.ByValue {
+		
+	};
+}

+ 53 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/Compositor_FrameTiming.java

@@ -0,0 +1,53 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1159</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class Compositor_FrameTiming extends Structure {
+	public int m_nSize;
+	public int m_nFrameIndex;
+	public int m_nNumFramePresents;
+	public int m_nNumMisPresented;
+	public int m_nNumDroppedFrames;
+	public int m_nReprojectionFlags;
+	public double m_flSystemTimeInSeconds;
+	public float m_flPreSubmitGpuMs;
+	public float m_flPostSubmitGpuMs;
+	public float m_flTotalRenderGpuMs;
+	public float m_flCompositorRenderGpuMs;
+	public float m_flCompositorRenderCpuMs;
+	public float m_flCompositorIdleCpuMs;
+	public float m_flClientFrameIntervalMs;
+	public float m_flPresentCallCpuMs;
+	public float m_flWaitForPresentCpuMs;
+	public float m_flSubmitFrameMs;
+	public float m_flWaitGetPosesCalledMs;
+	public float m_flNewPosesReadyMs;
+	public float m_flNewFrameReadyMs;
+	public float m_flCompositorUpdateStartMs;
+	public float m_flCompositorUpdateEndMs;
+	public float m_flCompositorRenderStartMs;
+	/** C type : TrackedDevicePose_t */
+	public TrackedDevicePose_t m_HmdPose;
+	public Compositor_FrameTiming() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("m_nSize", "m_nFrameIndex", "m_nNumFramePresents", "m_nNumMisPresented", "m_nNumDroppedFrames", "m_nReprojectionFlags", "m_flSystemTimeInSeconds", "m_flPreSubmitGpuMs", "m_flPostSubmitGpuMs", "m_flTotalRenderGpuMs", "m_flCompositorRenderGpuMs", "m_flCompositorRenderCpuMs", "m_flCompositorIdleCpuMs", "m_flClientFrameIntervalMs", "m_flPresentCallCpuMs", "m_flWaitForPresentCpuMs", "m_flSubmitFrameMs", "m_flWaitGetPosesCalledMs", "m_flNewPosesReadyMs", "m_flNewFrameReadyMs", "m_flCompositorUpdateStartMs", "m_flCompositorUpdateEndMs", "m_flCompositorRenderStartMs", "m_HmdPose");
+	}
+	public Compositor_FrameTiming(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends Compositor_FrameTiming implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends Compositor_FrameTiming implements Structure.ByValue {
+		
+	};
+}

+ 43 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/Compositor_OverlaySettings.java

@@ -0,0 +1,43 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1117</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class Compositor_OverlaySettings extends Structure {
+	public int size;
+	public byte curved;
+	public byte antialias;
+	public float scale;
+	public float distance;
+	public float alpha;
+	public float uOffset;
+	public float vOffset;
+	public float uScale;
+	public float vScale;
+	public float gridDivs;
+	public float gridWidth;
+	public float gridScale;
+	/** C type : HmdMatrix44_t */
+	public HmdMatrix44_t transform;
+	public Compositor_OverlaySettings() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("size", "curved", "antialias", "scale", "distance", "alpha", "uOffset", "vOffset", "uScale", "vScale", "gridDivs", "gridWidth", "gridScale", "transform");
+	}
+	public Compositor_OverlaySettings(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends Compositor_OverlaySettings implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends Compositor_OverlaySettings implements Structure.ByValue {
+		
+	};
+}

+ 53 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/D3D12TextureData_t.java

@@ -0,0 +1,53 @@
+package com.jme3.system.jopenvr;
+import com.jme3.system.jopenvr.JOpenVRLibrary.ID3D12CommandQueue;
+import com.jme3.system.jopenvr.JOpenVRLibrary.ID3D12Resource;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1003</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class D3D12TextureData_t extends Structure {
+	/**
+	 * struct ID3D12Resource *<br>
+	 * C type : ID3D12Resource*
+	 */
+	public ID3D12Resource m_pResource;
+	/**
+	 * struct ID3D12CommandQueue *<br>
+	 * C type : ID3D12CommandQueue*
+	 */
+	public ID3D12CommandQueue m_pCommandQueue;
+	public int m_nNodeMask;
+	public D3D12TextureData_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("m_pResource", "m_pCommandQueue", "m_nNodeMask");
+	}
+	/**
+	 * @param m_pResource struct ID3D12Resource *<br>
+	 * C type : ID3D12Resource*<br>
+	 * @param m_pCommandQueue struct ID3D12CommandQueue *<br>
+	 * C type : ID3D12CommandQueue*
+	 */
+	public D3D12TextureData_t(ID3D12Resource m_pResource, ID3D12CommandQueue m_pCommandQueue, int m_nNodeMask) {
+		super();
+		this.m_pResource = m_pResource;
+		this.m_pCommandQueue = m_pCommandQueue;
+		this.m_nNodeMask = m_nNodeMask;
+	}
+	public D3D12TextureData_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends D3D12TextureData_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends D3D12TextureData_t implements Structure.ByValue {
+		
+	};
+}

+ 63 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/DistortionCoordinates_t.java

@@ -0,0 +1,63 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:954</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class DistortionCoordinates_t extends Structure {
+	/**
+	 * float[2]<br>
+	 * C type : float[2]
+	 */
+	public float[] rfRed = new float[2];
+	/**
+	 * float[2]<br>
+	 * C type : float[2]
+	 */
+	public float[] rfGreen = new float[2];
+	/**
+	 * float[2]<br>
+	 * C type : float[2]
+	 */
+	public float[] rfBlue = new float[2];
+	public DistortionCoordinates_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("rfRed", "rfGreen", "rfBlue");
+	}
+	/**
+	 * @param rfRed float[2]<br>
+	 * C type : float[2]<br>
+	 * @param rfGreen float[2]<br>
+	 * C type : float[2]<br>
+	 * @param rfBlue float[2]<br>
+	 * C type : float[2]
+	 */
+	public DistortionCoordinates_t(float rfRed[], float rfGreen[], float rfBlue[]) {
+		super();
+		if ((rfRed.length != this.rfRed.length)) 
+			throw new IllegalArgumentException("Wrong array size !");
+		this.rfRed = rfRed;
+		if ((rfGreen.length != this.rfGreen.length)) 
+			throw new IllegalArgumentException("Wrong array size !");
+		this.rfGreen = rfGreen;
+		if ((rfBlue.length != this.rfBlue.length)) 
+			throw new IllegalArgumentException("Wrong array size !");
+		this.rfBlue = rfBlue;
+	}
+	public DistortionCoordinates_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends DistortionCoordinates_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends DistortionCoordinates_t implements Structure.ByValue {
+		
+	};
+}

+ 43 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/HiddenAreaMesh_t.java

@@ -0,0 +1,43 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1090</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class HiddenAreaMesh_t extends Structure {
+	/**
+	 * const struct vr::HmdVector2_t *<br>
+	 * C type : HmdVector2_t*
+	 */
+	public com.jme3.system.jopenvr.HmdVector2_t.ByReference pVertexData;
+	public int unTriangleCount;
+	public HiddenAreaMesh_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("pVertexData", "unTriangleCount");
+	}
+	/**
+	 * @param pVertexData const struct vr::HmdVector2_t *<br>
+	 * C type : HmdVector2_t*
+	 */
+	public HiddenAreaMesh_t(com.jme3.system.jopenvr.HmdVector2_t.ByReference pVertexData, int unTriangleCount) {
+		super();
+		this.pVertexData = pVertexData;
+		this.unTriangleCount = unTriangleCount;
+	}
+	public HiddenAreaMesh_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends HiddenAreaMesh_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends HiddenAreaMesh_t implements Structure.ByValue {
+		
+	};
+}

+ 39 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/HmdColor_t.java

@@ -0,0 +1,39 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:938</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class HmdColor_t extends Structure {
+	public float r;
+	public float g;
+	public float b;
+	public float a;
+	public HmdColor_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("r", "g", "b", "a");
+	}
+	public HmdColor_t(float r, float g, float b, float a) {
+		super();
+		this.r = r;
+		this.g = g;
+		this.b = b;
+		this.a = a;
+	}
+	public HmdColor_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends HmdColor_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends HmdColor_t implements Structure.ByValue {
+		
+	};
+}

+ 43 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/HmdMatrix34_t.java

@@ -0,0 +1,43 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:906</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class HmdMatrix34_t extends Structure {
+	/**
+	 * float[3][4]<br>
+	 * C type : float[3][4]
+	 */
+	public float[] m = new float[((3) * (4))];
+	public HmdMatrix34_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("m");
+	}
+	/**
+	 * @param m float[3][4]<br>
+	 * C type : float[3][4]
+	 */
+	public HmdMatrix34_t(float m[]) {
+		super();
+		if ((m.length != this.m.length)) 
+			throw new IllegalArgumentException("Wrong array size !");
+		this.m = m;
+	}
+	public HmdMatrix34_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends HmdMatrix34_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends HmdMatrix34_t implements Structure.ByValue {
+		
+	};
+}

+ 43 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/HmdMatrix44_t.java

@@ -0,0 +1,43 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:910</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class HmdMatrix44_t extends Structure {
+	/**
+	 * float[4][4]<br>
+	 * C type : float[4][4]
+	 */
+	public float[] m = new float[((4) * (4))];
+	public HmdMatrix44_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("m");
+	}
+	/**
+	 * @param m float[4][4]<br>
+	 * C type : float[4][4]
+	 */
+	public HmdMatrix44_t(float m[]) {
+		super();
+		if ((m.length != this.m.length)) 
+			throw new IllegalArgumentException("Wrong array size !");
+		this.m = m;
+	}
+	public HmdMatrix44_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends HmdMatrix44_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends HmdMatrix44_t implements Structure.ByValue {
+		
+	};
+}

+ 43 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/HmdQuad_t.java

@@ -0,0 +1,43 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:942</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class HmdQuad_t extends Structure {
+	/**
+	 * struct vr::HmdVector3_t[4]<br>
+	 * C type : HmdVector3_t[4]
+	 */
+	public HmdVector3_t[] vCorners = new HmdVector3_t[4];
+	public HmdQuad_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("vCorners");
+	}
+	/**
+	 * @param vCorners struct vr::HmdVector3_t[4]<br>
+	 * C type : HmdVector3_t[4]
+	 */
+	public HmdQuad_t(HmdVector3_t vCorners[]) {
+		super();
+		if ((vCorners.length != this.vCorners.length)) 
+			throw new IllegalArgumentException("Wrong array size !");
+		this.vCorners = vCorners;
+	}
+	public HmdQuad_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends HmdQuad_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends HmdQuad_t implements Structure.ByValue {
+		
+	};
+}

+ 39 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/HmdQuaternion_t.java

@@ -0,0 +1,39 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:932</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class HmdQuaternion_t extends Structure {
+	public double w;
+	public double x;
+	public double y;
+	public double z;
+	public HmdQuaternion_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("w", "x", "y", "z");
+	}
+	public HmdQuaternion_t(double w, double x, double y, double z) {
+		super();
+		this.w = w;
+		this.x = x;
+		this.y = y;
+		this.z = z;
+	}
+	public HmdQuaternion_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends HmdQuaternion_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends HmdQuaternion_t implements Structure.ByValue {
+		
+	};
+}

+ 41 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/HmdRect2_t.java

@@ -0,0 +1,41 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:946</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class HmdRect2_t extends Structure {
+	/** C type : HmdVector2_t */
+	public HmdVector2_t vTopLeft;
+	/** C type : HmdVector2_t */
+	public HmdVector2_t vBottomRight;
+	public HmdRect2_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("vTopLeft", "vBottomRight");
+	}
+	/**
+	 * @param vTopLeft C type : HmdVector2_t<br>
+	 * @param vBottomRight C type : HmdVector2_t
+	 */
+	public HmdRect2_t(HmdVector2_t vTopLeft, HmdVector2_t vBottomRight) {
+		super();
+		this.vTopLeft = vTopLeft;
+		this.vBottomRight = vBottomRight;
+	}
+	public HmdRect2_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends HmdRect2_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends HmdRect2_t implements Structure.ByValue {
+		
+	};
+}

+ 43 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/HmdVector2_t.java

@@ -0,0 +1,43 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:926</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class HmdVector2_t extends Structure {
+	/**
+	 * float[2]<br>
+	 * C type : float[2]
+	 */
+	public float[] v = new float[2];
+	public HmdVector2_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("v");
+	}
+	/**
+	 * @param v float[2]<br>
+	 * C type : float[2]
+	 */
+	public HmdVector2_t(float v[]) {
+		super();
+		if ((v.length != this.v.length)) 
+			throw new IllegalArgumentException("Wrong array size !");
+		this.v = v;
+	}
+	public HmdVector2_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends HmdVector2_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends HmdVector2_t implements Structure.ByValue {
+		
+	};
+}

+ 43 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/HmdVector3_t.java

@@ -0,0 +1,43 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:914</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class HmdVector3_t extends Structure {
+	/**
+	 * float[3]<br>
+	 * C type : float[3]
+	 */
+	public float[] v = new float[3];
+	public HmdVector3_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("v");
+	}
+	/**
+	 * @param v float[3]<br>
+	 * C type : float[3]
+	 */
+	public HmdVector3_t(float v[]) {
+		super();
+		if ((v.length != this.v.length)) 
+			throw new IllegalArgumentException("Wrong array size !");
+		this.v = v;
+	}
+	public HmdVector3_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends HmdVector3_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends HmdVector3_t implements Structure.ByValue {
+		
+	};
+}

+ 43 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/HmdVector3d_t.java

@@ -0,0 +1,43 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:922</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class HmdVector3d_t extends Structure {
+	/**
+	 * double[3]<br>
+	 * C type : double[3]
+	 */
+	public double[] v = new double[3];
+	public HmdVector3d_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("v");
+	}
+	/**
+	 * @param v double[3]<br>
+	 * C type : double[3]
+	 */
+	public HmdVector3d_t(double v[]) {
+		super();
+		if ((v.length != this.v.length)) 
+			throw new IllegalArgumentException("Wrong array size !");
+		this.v = v;
+	}
+	public HmdVector3d_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends HmdVector3d_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends HmdVector3d_t implements Structure.ByValue {
+		
+	};
+}

+ 43 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/HmdVector4_t.java

@@ -0,0 +1,43 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:918</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class HmdVector4_t extends Structure {
+	/**
+	 * float[4]<br>
+	 * C type : float[4]
+	 */
+	public float[] v = new float[4];
+	public HmdVector4_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("v");
+	}
+	/**
+	 * @param v float[4]<br>
+	 * C type : float[4]
+	 */
+	public HmdVector4_t(float v[]) {
+		super();
+		if ((v.length != this.v.length)) 
+			throw new IllegalArgumentException("Wrong array size !");
+		this.v = v;
+	}
+	public HmdVector4_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends HmdVector4_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends HmdVector4_t implements Structure.ByValue {
+		
+	};
+}

+ 37 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/IntersectionMaskCircle_t.java

@@ -0,0 +1,37 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1200</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class IntersectionMaskCircle_t extends Structure {
+	public float m_flCenterX;
+	public float m_flCenterY;
+	public float m_flRadius;
+	public IntersectionMaskCircle_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("m_flCenterX", "m_flCenterY", "m_flRadius");
+	}
+	public IntersectionMaskCircle_t(float m_flCenterX, float m_flCenterY, float m_flRadius) {
+		super();
+		this.m_flCenterX = m_flCenterX;
+		this.m_flCenterY = m_flCenterY;
+		this.m_flRadius = m_flRadius;
+	}
+	public IntersectionMaskCircle_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends IntersectionMaskCircle_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends IntersectionMaskCircle_t implements Structure.ByValue {
+		
+	};
+}

+ 39 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/IntersectionMaskRectangle_t.java

@@ -0,0 +1,39 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1195</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class IntersectionMaskRectangle_t extends Structure {
+	public float m_flTopLeftX;
+	public float m_flTopLeftY;
+	public float m_flWidth;
+	public float m_flHeight;
+	public IntersectionMaskRectangle_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("m_flTopLeftX", "m_flTopLeftY", "m_flWidth", "m_flHeight");
+	}
+	public IntersectionMaskRectangle_t(float m_flTopLeftX, float m_flTopLeftY, float m_flWidth, float m_flHeight) {
+		super();
+		this.m_flTopLeftX = m_flTopLeftX;
+		this.m_flTopLeftY = m_flTopLeftY;
+		this.m_flWidth = m_flWidth;
+		this.m_flHeight = m_flHeight;
+	}
+	public IntersectionMaskRectangle_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends IntersectionMaskRectangle_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends IntersectionMaskRectangle_t implements Structure.ByValue {
+		
+	};
+}

+ 1841 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/JOpenVRLibrary.java

@@ -0,0 +1,1841 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Library;
+import com.sun.jna.Native;
+import com.sun.jna.NativeLibrary;
+import com.sun.jna.Pointer;
+import com.sun.jna.PointerType;
+import com.sun.jna.ptr.IntByReference;
+import java.nio.IntBuffer;
+/**
+ * JNA Wrapper for library <b>JOpenVR</b><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class JOpenVRLibrary implements Library {
+	
+	/**
+	 * Get the version of the underlying OpenVR API.<br>
+	 * see <a href="https://github.com/ValveSoftware/openvr/tree/v1.0.6">https://github.com/ValveSoftware/openvr/tree/v1.0.6</a>.
+	 */
+	public static final String OPENVR_VERSION = "1.0.6";
+	
+	/**
+	 * Get the commit number of the underlying OpenVR API.
+	 * see <a href="https://github.com/ValveSoftware/openvr/commit/7fa6470f2972970859f2395f1390f6d87d4b0fc3">https://github.com/ValveSoftware/openvr/commit/7fa6470f2972970859f2395f1390f6d87d4b0fc3</a>
+	 */
+	public static final String OPENVR_COMMIT  = "7fa6470";
+	
+	public static final String JNA_LIBRARY_NAME = "openvr_api";
+	public static final NativeLibrary JNA_NATIVE_LIB = NativeLibrary.getInstance(JOpenVRLibrary.JNA_LIBRARY_NAME);
+	static {
+		Native.register(JOpenVRLibrary.class, JOpenVRLibrary.JNA_NATIVE_LIB);
+	}
+
+	// OpenVR Constants
+	public static final int k_unMaxDriverDebugResponseSize = 32768;
+	public static final int k_unTrackedDeviceIndex_Hmd     = 0;
+	public static final int k_unMaxTrackedDeviceCount      = 16;
+	public static final long k_unTrackedDeviceIndexOther   = 4294967294L;
+	public static final long k_unTrackedDeviceIndexInvalid = 4294967295L;
+	public static final long k_ulInvalidPropertyContainer  = 0;
+	public static final int k_unInvalidPropertyTag         = 0;
+	public static final int k_unFloatPropertyTag           = 1;
+	public static final int k_unInt32PropertyTag           = 2;
+	public static final int k_unUint64PropertyTag          = 3;
+	public static final int k_unBoolPropertyTag            = 4;
+	public static final int k_unStringPropertyTag          = 5;
+	public static final int k_unHmdMatrix34PropertyTag     = 20;
+	public static final int k_unHmdMatrix44PropertyTag     = 21;
+	public static final int k_unHmdVector3PropertyTag      = 22;
+	public static final int k_unHmdVector4PropertyTag = 23;
+	public static final int k_unHiddenAreaPropertyTag = 30;
+	public static final int k_unOpenVRInternalReserved_Start = 1000;
+	public static final int k_unOpenVRInternalReserved_End = 10000;
+	public static final int k_unMaxPropertyStringSize = 32768;
+	public static final int k_unControllerStateAxisCount = 5;
+	public static final long k_ulOverlayHandleInvalid = 0;
+	public static final int k_unScreenshotHandleInvalid = 0;
+	public static final int k_unMaxApplicationKeyLength = 128;
+	public static final String k_pch_MimeType_HomeApp = "vr/home";
+	public static final String k_pch_MimeType_GameTheater = "vr/game_theater";
+	public static final String IVRApplications_Version = "FnTable:IVRApplications_006";
+	public static final int k_unVROverlayMaxKeyLength = 128;
+	public static final int k_unVROverlayMaxNameLength = 128;
+	public static final int k_unMaxOverlayCount = 64;
+	public static final int k_unMaxOverlayIntersectionMaskPrimitivesCount = 32;
+	public static final String IVROverlay_Version = "FnTable:IVROverlay_014";
+	public static final String k_pch_Controller_Component_GDC2015 = "gdc2015";
+	public static final String k_pch_Controller_Component_Base = "base";
+	public static final String k_pch_Controller_Component_Tip = "tip";
+	public static final String k_pch_Controller_Component_HandGrip = "handgrip";
+	public static final String k_pch_Controller_Component_Status = "status";
+	public static final String IVRRenderModels_Version = "FnTable:IVRRenderModels_005";
+	public static final int k_unNotificationTextMaxSize = 256;
+	public static final String IVRNotifications_Version = "FnTable:IVRNotifications_002";
+	public static final int k_unMaxSettingsKeyLength = 128;
+	public static final String IVRSettings_Version = "FnTable:IVRSettings_002";
+	public static final String k_pch_SteamVR_Section = "steamvr";
+	public static final String k_pch_SteamVR_RequireHmd_String = "requireHmd";
+	public static final String k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver";
+	public static final String k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd";
+	public static final String k_pch_SteamVR_DisplayDebug_Bool = "displayDebug";
+	public static final String k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe";
+	public static final String k_pch_SteamVR_EnableDistortion_Bool = "enableDistortion";
+	public static final String k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX";
+	public static final String k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY";
+	public static final String k_pch_SteamVR_SendSystemButtonToAllApps_Bool = "sendSystemButtonToAllApps";
+	public static final String k_pch_SteamVR_LogLevel_Int32 = "loglevel";
+	public static final String k_pch_SteamVR_IPD_Float = "ipd";
+	public static final String k_pch_SteamVR_Background_String = "background";
+	public static final String k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection";
+	public static final String k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight";
+	public static final String k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius";
+	public static final String k_pch_SteamVR_GridColor_String = "gridColor";
+	public static final String k_pch_SteamVR_PlayAreaColor_String = "playAreaColor";
+	public static final String k_pch_SteamVR_ShowStage_Bool = "showStage";
+	public static final String k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers";
+	public static final String k_pch_SteamVR_DirectMode_Bool = "directMode";
+	public static final String k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid";
+	public static final String k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid";
+	public static final String k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers";
+	public static final String k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees";
+	public static final String k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement";
+	public static final String k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses";
+	public static final String k_pch_SteamVR_RenderTargetMultiplier_Float = "renderTargetMultiplier";
+	public static final String k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection";
+	public static final String k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection";
+	public static final String k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection";
+	public static final String k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking";
+	public static final String k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView";
+	public static final String k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView";
+	public static final String k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry";
+	public static final String k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch";
+	public static final String k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch";
+	public static final String k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch";
+	public static final String k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard";
+	public static final String k_pch_SteamVR_EnableHomeApp = "enableHomeApp";
+	public static final String k_pch_SteamVR_SetInitialDefaultHomeApp = "setInitialDefaultHomeApp";
+	public static final String k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec";
+	public static final String k_pch_SteamVR_RetailDemo_Bool = "retailDemo";
+	public static final String k_pch_SteamVR_IpdOffset_Float = "ipdOffset";
+	public static final String k_pch_Lighthouse_Section = "driver_lighthouse";
+	public static final String k_pch_Lighthouse_DisableIMU_Bool = "disableimu";
+	public static final String k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation";
+	public static final String k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug";
+	public static final String k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation";
+	public static final String k_pch_Lighthouse_DBHistory_Bool = "dbhistory";
+	public static final String k_pch_Null_Section = "driver_null";
+	public static final String k_pch_Null_SerialNumber_String = "serialNumber";
+	public static final String k_pch_Null_ModelNumber_String = "modelNumber";
+	public static final String k_pch_Null_WindowX_Int32 = "windowX";
+	public static final String k_pch_Null_WindowY_Int32 = "windowY";
+	public static final String k_pch_Null_WindowWidth_Int32 = "windowWidth";
+	public static final String k_pch_Null_WindowHeight_Int32 = "windowHeight";
+	public static final String k_pch_Null_RenderWidth_Int32 = "renderWidth";
+	public static final String k_pch_Null_RenderHeight_Int32 = "renderHeight";
+	public static final String k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons";
+	public static final String k_pch_Null_DisplayFrequency_Float = "displayFrequency";
+	public static final String k_pch_UserInterface_Section = "userinterface";
+	public static final String k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop";
+	public static final String k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray";
+	public static final String k_pch_UserInterface_Screenshots_Bool = "screenshots";
+	public static final String k_pch_UserInterface_ScreenshotType_Int = "screenshotType";
+	public static final String k_pch_Notifications_Section = "notifications";
+	public static final String k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb";
+	public static final String k_pch_Keyboard_Section = "keyboard";
+	public static final String k_pch_Keyboard_TutorialCompletions = "TutorialCompletions";
+	public static final String k_pch_Keyboard_ScaleX = "ScaleX";
+	public static final String k_pch_Keyboard_ScaleY = "ScaleY";
+	public static final String k_pch_Keyboard_OffsetLeftX = "OffsetLeftX";
+	public static final String k_pch_Keyboard_OffsetRightX = "OffsetRightX";
+	public static final String k_pch_Keyboard_OffsetY = "OffsetY";
+	public static final String k_pch_Keyboard_Smoothing = "Smoothing";
+	public static final String k_pch_Perf_Section = "perfcheck";
+	public static final String k_pch_Perf_HeuristicActive_Bool = "heuristicActive";
+	public static final String k_pch_Perf_NotifyInHMD_Bool = "warnInHMD";
+	public static final String k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce";
+	public static final String k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore";
+	public static final String k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit";
+	public static final String k_pch_Perf_TestData_Float = "perfTestData";
+	public static final String k_pch_CollisionBounds_Section = "collisionBounds";
+	public static final String k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle";
+	public static final String k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn";
+	public static final String k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn";
+	public static final String k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn";
+	public static final String k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance";
+	public static final String k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR";
+	public static final String k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG";
+	public static final String k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB";
+	public static final String k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA";
+	public static final String k_pch_Camera_Section = "camera";
+	public static final String k_pch_Camera_EnableCamera_Bool = "enableCamera";
+	public static final String k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard";
+	public static final String k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds";
+	public static final String k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView";
+	public static final String k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR";
+	public static final String k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG";
+	public static final String k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB";
+	public static final String k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA";
+	public static final String k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength";
+	public static final String k_pch_audio_Section = "audio";
+	public static final String k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice";
+	public static final String k_pch_audio_OnRecordDevice_String = "onRecordDevice";
+	public static final String k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice";
+	public static final String k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice";
+	public static final String k_pch_audio_OffRecordDevice_String = "offRecordDevice";
+	public static final String k_pch_audio_VIVEHDMIGain = "viveHDMIGain";
+	public static final String k_pch_Power_Section = "power";
+	public static final String k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit";
+	public static final String k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout";
+	public static final String k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout";
+	public static final String k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout";
+	public static final String k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress";
+	public static final String k_pch_Dashboard_Section = "dashboard";
+	public static final String k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard";
+	public static final String k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode";
+	public static final String k_pch_modelskin_Section = "modelskins";
+	public static final String k_pch_Driver_Enable_Bool = "enable";
+
+	public static final String IVRSystem_Version          = "FnTable:IVRSystem_015";
+	public static final String IVRExtendedDisplay_Version = "FnTable:IVRExtendedDisplay_001";
+	public static final String IVRTrackedCamera_Version   = "FnTable:IVRTrackedCamera_003";
+	public static final String IVRChaperone_Version       = "FnTable:IVRChaperone_003";
+	public static final String IVRChaperoneSetup_Version  = "FnTable:IVRChaperoneSetup_005";
+	//public static final String IVRCompositor_Version      = "FnTable:IVRCompositor_020";
+	public static final String IVRCompositor_Version      = "FnTable:IVRCompositor_019";
+	public static final String IVRScreenshots_Version     = "FnTable:IVRScreenshots_001";
+	public static final String IVRResources_Version       = "FnTable:IVRResources_001";
+	
+	
+	
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:178</i><br>
+	 * enum values
+	 */
+	public static interface EVREye {
+		/** <i>native declaration : headers\openvr_capi.h:176</i> */
+		public static final int EVREye_Eye_Left = 0;
+		/** <i>native declaration : headers\openvr_capi.h:177</i> */
+		public static final int EVREye_Eye_Right = 1;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:185</i><br>
+	 * enum values
+	 */
+	public static interface ETextureType {
+		/** <i>native declaration : headers\openvr_capi.h:180</i> */
+		public static final int ETextureType_TextureType_DirectX = 0;
+		/** <i>native declaration : headers\openvr_capi.h:181</i> */
+		public static final int ETextureType_TextureType_OpenGL = 1;
+		/** <i>native declaration : headers\openvr_capi.h:182</i> */
+		public static final int ETextureType_TextureType_Vulkan = 2;
+		/** <i>native declaration : headers\openvr_capi.h:183</i> */
+		public static final int ETextureType_TextureType_IOSurface = 3;
+		/** <i>native declaration : headers\openvr_capi.h:184</i> */
+		public static final int ETextureType_TextureType_DirectX12 = 4;
+	};
+	
+	
+
+	
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:190</i><br>
+	 * enum values
+	 */
+	public static interface EColorSpace {
+		/** <i>native declaration : headers\openvr_capi.h:187</i> */
+		public static final int EColorSpace_ColorSpace_Auto = 0;
+		/** <i>native declaration : headers\openvr_capi.h:188</i> */
+		public static final int EColorSpace_ColorSpace_Gamma = 1;
+		/** <i>native declaration : headers\openvr_capi.h:189</i> */
+		public static final int EColorSpace_ColorSpace_Linear = 2;
+	};
+	
+
+	
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:197</i><br>
+	 * enum values
+	 */
+	public static interface ETrackingResult {
+		/** <i>native declaration : headers\openvr_capi.h:192</i> */
+		public static final int ETrackingResult_TrackingResult_Uninitialized = 1;
+		/** <i>native declaration : headers\openvr_capi.h:193</i> */
+		public static final int ETrackingResult_TrackingResult_Calibrating_InProgress = 100;
+		/** <i>native declaration : headers\openvr_capi.h:194</i> */
+		public static final int ETrackingResult_TrackingResult_Calibrating_OutOfRange = 101;
+		/** <i>native declaration : headers\openvr_capi.h:195</i> */
+		public static final int ETrackingResult_TrackingResult_Running_OK = 200;
+		/** <i>native declaration : headers\openvr_capi.h:196</i> */
+		public static final int ETrackingResult_TrackingResult_Running_OutOfRange = 201;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:204</i><br>
+	 * enum values
+	 */
+	public static interface ETrackedDeviceClass {
+		/** <i>native declaration : headers\openvr_capi.h:199</i> */
+		public static final int ETrackedDeviceClass_TrackedDeviceClass_Invalid = 0;
+		/** <i>native declaration : headers\openvr_capi.h:200</i> */
+		public static final int ETrackedDeviceClass_TrackedDeviceClass_HMD = 1;
+		/** <i>native declaration : headers\openvr_capi.h:201</i> */
+		public static final int ETrackedDeviceClass_TrackedDeviceClass_Controller = 2;
+		/** <i>native declaration : headers\openvr_capi.h:202</i> */
+		public static final int ETrackedDeviceClass_TrackedDeviceClass_GenericTracker = 3;
+		/** <i>native declaration : headers\openvr_capi.h:203</i> */
+		public static final int ETrackedDeviceClass_TrackedDeviceClass_TrackingReference = 4;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:209</i><br>
+	 * enum values
+	 */
+	public static interface ETrackedControllerRole {
+		/** <i>native declaration : headers\openvr_capi.h:206</i> */
+		public static final int ETrackedControllerRole_TrackedControllerRole_Invalid = 0;
+		/** <i>native declaration : headers\openvr_capi.h:207</i> */
+		public static final int ETrackedControllerRole_TrackedControllerRole_LeftHand = 1;
+		/** <i>native declaration : headers\openvr_capi.h:208</i> */
+		public static final int ETrackedControllerRole_TrackedControllerRole_RightHand = 2;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:214</i><br>
+	 * enum values
+	 */
+	public static interface ETrackingUniverseOrigin {
+		/** <i>native declaration : headers\openvr_capi.h:211</i> */
+		public static final int ETrackingUniverseOrigin_TrackingUniverseSeated = 0;
+		/** <i>native declaration : headers\openvr_capi.h:212</i> */
+		public static final int ETrackingUniverseOrigin_TrackingUniverseStanding = 1;
+		/** <i>native declaration : headers\openvr_capi.h:213</i> */
+		public static final int ETrackingUniverseOrigin_TrackingUniverseRawAndUncalibrated = 2;
+	};
+	/**
+     * The enumeration of tracked devices properties.
+	 */
+	public static interface ETrackedDeviceProperty {
+
+        /**
+         * An invalid property.
+         */
+		public static final int ETrackedDeviceProperty_Prop_Invalid = 0;
+		
+		/**
+		 * The tracking system name property (String).
+		 */
+		public static final int ETrackedDeviceProperty_Prop_TrackingSystemName_String = 1000;
+		
+		/**
+		 * The tracking system <code>model number</code> property (String).
+		 */
+		public static final int ETrackedDeviceProperty_Prop_ModelNumber_String = 1001;
+		
+		/**
+		 * The tracking system <code>serial number</code> property (String).
+		 */
+		public static final int ETrackedDeviceProperty_Prop_SerialNumber_String = 1002;
+		
+		/**
+		 * The tracking system <code>render model name</code> property (String).
+		 */
+		public static final int ETrackedDeviceProperty_Prop_RenderModelName_String = 1003;
+		
+		/**
+		 * The tracking system <code>will drift in yaw</code> property (<code>bool</code>).
+		 */
+		public static final int ETrackedDeviceProperty_Prop_WillDriftInYaw_Bool = 1004;
+		
+		/**
+		 * The tracking system <code>manufacturer name</code> property (String).
+		 */
+		public static final int ETrackedDeviceProperty_Prop_ManufacturerName_String = 1005;
+		
+		/**
+		 * The tracking system <code>tracking firmware version</code> property (String).
+		 */
+		public static final int ETrackedDeviceProperty_Prop_TrackingFirmwareVersion_String = 1006;
+		
+		/**
+		 * The tracking system <code>hardware revision</code> property (String).
+		 */
+		public static final int ETrackedDeviceProperty_Prop_HardwareRevision_String = 1007;
+		
+		/**
+		 * The tracking system <code>all wireless dongle descriptions</code> property (String).
+		 */
+		public static final int ETrackedDeviceProperty_Prop_AllWirelessDongleDescriptions_String = 1008;
+		/** <i>native declaration : headers\openvr_capi.h:226</i> */
+		public static final int ETrackedDeviceProperty_Prop_ConnectedWirelessDongle_String = 1009;
+		/** <i>native declaration : headers\openvr_capi.h:227</i> */
+		public static final int ETrackedDeviceProperty_Prop_DeviceIsWireless_Bool = 1010;
+		/** <i>native declaration : headers\openvr_capi.h:228</i> */
+		public static final int ETrackedDeviceProperty_Prop_DeviceIsCharging_Bool = 1011;
+		/** <i>native declaration : headers\openvr_capi.h:229</i> */
+		public static final int ETrackedDeviceProperty_Prop_DeviceBatteryPercentage_Float = 1012;
+		/** <i>native declaration : headers\openvr_capi.h:230</i> */
+		public static final int ETrackedDeviceProperty_Prop_StatusDisplayTransform_Matrix34 = 1013;
+		/** <i>native declaration : headers\openvr_capi.h:231</i> */
+		public static final int ETrackedDeviceProperty_Prop_Firmware_UpdateAvailable_Bool = 1014;
+		/** <i>native declaration : headers\openvr_capi.h:232</i> */
+		public static final int ETrackedDeviceProperty_Prop_Firmware_ManualUpdate_Bool = 1015;
+		/** <i>native declaration : headers\openvr_capi.h:233</i> */
+		public static final int ETrackedDeviceProperty_Prop_Firmware_ManualUpdateURL_String = 1016;
+		/** <i>native declaration : headers\openvr_capi.h:234</i> */
+		public static final int ETrackedDeviceProperty_Prop_HardwareRevision_Uint64 = 1017;
+		/** <i>native declaration : headers\openvr_capi.h:235</i> */
+		public static final int ETrackedDeviceProperty_Prop_FirmwareVersion_Uint64 = 1018;
+		/** <i>native declaration : headers\openvr_capi.h:236</i> */
+		public static final int ETrackedDeviceProperty_Prop_FPGAVersion_Uint64 = 1019;
+		/** <i>native declaration : headers\openvr_capi.h:237</i> */
+		public static final int ETrackedDeviceProperty_Prop_VRCVersion_Uint64 = 1020;
+		/** <i>native declaration : headers\openvr_capi.h:238</i> */
+		public static final int ETrackedDeviceProperty_Prop_RadioVersion_Uint64 = 1021;
+		/** <i>native declaration : headers\openvr_capi.h:239</i> */
+		public static final int ETrackedDeviceProperty_Prop_DongleVersion_Uint64 = 1022;
+		/** <i>native declaration : headers\openvr_capi.h:240</i> */
+		public static final int ETrackedDeviceProperty_Prop_BlockServerShutdown_Bool = 1023;
+		/** <i>native declaration : headers\openvr_capi.h:241</i> */
+		public static final int ETrackedDeviceProperty_Prop_CanUnifyCoordinateSystemWithHmd_Bool = 1024;
+		/** <i>native declaration : headers\openvr_capi.h:242</i> */
+		public static final int ETrackedDeviceProperty_Prop_ContainsProximitySensor_Bool = 1025;
+		/** <i>native declaration : headers\openvr_capi.h:243</i> */
+		public static final int ETrackedDeviceProperty_Prop_DeviceProvidesBatteryStatus_Bool = 1026;
+		/** <i>native declaration : headers\openvr_capi.h:244</i> */
+		public static final int ETrackedDeviceProperty_Prop_DeviceCanPowerOff_Bool = 1027;
+		/** <i>native declaration : headers\openvr_capi.h:245</i> */
+		public static final int ETrackedDeviceProperty_Prop_Firmware_ProgrammingTarget_String = 1028;
+		/** <i>native declaration : headers\openvr_capi.h:246</i> */
+		public static final int ETrackedDeviceProperty_Prop_DeviceClass_Int32 = 1029;
+		/** <i>native declaration : headers\openvr_capi.h:247</i> */
+		public static final int ETrackedDeviceProperty_Prop_HasCamera_Bool = 1030;
+		/** <i>native declaration : headers\openvr_capi.h:248</i> */
+		public static final int ETrackedDeviceProperty_Prop_DriverVersion_String = 1031;
+		/** <i>native declaration : headers\openvr_capi.h:249</i> */
+		public static final int ETrackedDeviceProperty_Prop_Firmware_ForceUpdateRequired_Bool = 1032;
+		/** <i>native declaration : headers\openvr_capi.h:250</i> */
+		public static final int ETrackedDeviceProperty_Prop_ViveSystemButtonFixRequired_Bool = 1033;
+		/** <i>native declaration : headers\openvr_capi.h:251</i> */
+		public static final int ETrackedDeviceProperty_Prop_ParentDriver_Uint64 = 1034;
+		/** <i>native declaration : headers\openvr_capi.h:252</i> */
+		public static final int ETrackedDeviceProperty_Prop_ReportsTimeSinceVSync_Bool = 2000;
+		/** <i>native declaration : headers\openvr_capi.h:253</i> */
+		public static final int ETrackedDeviceProperty_Prop_SecondsFromVsyncToPhotons_Float = 2001;
+		/** <i>native declaration : headers\openvr_capi.h:254</i> */
+		public static final int ETrackedDeviceProperty_Prop_DisplayFrequency_Float = 2002;
+		/** <i>native declaration : headers\openvr_capi.h:255</i> */
+		public static final int ETrackedDeviceProperty_Prop_UserIpdMeters_Float = 2003;
+		/** <i>native declaration : headers\openvr_capi.h:256</i> */
+		public static final int ETrackedDeviceProperty_Prop_CurrentUniverseId_Uint64 = 2004;
+		/** <i>native declaration : headers\openvr_capi.h:257</i> */
+		public static final int ETrackedDeviceProperty_Prop_PreviousUniverseId_Uint64 = 2005;
+		/** <i>native declaration : headers\openvr_capi.h:258</i> */
+		public static final int ETrackedDeviceProperty_Prop_DisplayFirmwareVersion_Uint64 = 2006;
+		/** <i>native declaration : headers\openvr_capi.h:259</i> */
+		public static final int ETrackedDeviceProperty_Prop_IsOnDesktop_Bool = 2007;
+		/** <i>native declaration : headers\openvr_capi.h:260</i> */
+		public static final int ETrackedDeviceProperty_Prop_DisplayMCType_Int32 = 2008;
+		/** <i>native declaration : headers\openvr_capi.h:261</i> */
+		public static final int ETrackedDeviceProperty_Prop_DisplayMCOffset_Float = 2009;
+		/** <i>native declaration : headers\openvr_capi.h:262</i> */
+		public static final int ETrackedDeviceProperty_Prop_DisplayMCScale_Float = 2010;
+		/** <i>native declaration : headers\openvr_capi.h:263</i> */
+		public static final int ETrackedDeviceProperty_Prop_EdidVendorID_Int32 = 2011;
+		/** <i>native declaration : headers\openvr_capi.h:264</i> */
+		public static final int ETrackedDeviceProperty_Prop_DisplayMCImageLeft_String = 2012;
+		/** <i>native declaration : headers\openvr_capi.h:265</i> */
+		public static final int ETrackedDeviceProperty_Prop_DisplayMCImageRight_String = 2013;
+		/** <i>native declaration : headers\openvr_capi.h:266</i> */
+		public static final int ETrackedDeviceProperty_Prop_DisplayGCBlackClamp_Float = 2014;
+		/** <i>native declaration : headers\openvr_capi.h:267</i> */
+		public static final int ETrackedDeviceProperty_Prop_EdidProductID_Int32 = 2015;
+		/** <i>native declaration : headers\openvr_capi.h:268</i> */
+		public static final int ETrackedDeviceProperty_Prop_CameraToHeadTransform_Matrix34 = 2016;
+		/** <i>native declaration : headers\openvr_capi.h:269</i> */
+		public static final int ETrackedDeviceProperty_Prop_DisplayGCType_Int32 = 2017;
+		/** <i>native declaration : headers\openvr_capi.h:270</i> */
+		public static final int ETrackedDeviceProperty_Prop_DisplayGCOffset_Float = 2018;
+		/** <i>native declaration : headers\openvr_capi.h:271</i> */
+		public static final int ETrackedDeviceProperty_Prop_DisplayGCScale_Float = 2019;
+		/** <i>native declaration : headers\openvr_capi.h:272</i> */
+		public static final int ETrackedDeviceProperty_Prop_DisplayGCPrescale_Float = 2020;
+		/** <i>native declaration : headers\openvr_capi.h:273</i> */
+		public static final int ETrackedDeviceProperty_Prop_DisplayGCImage_String = 2021;
+		/** <i>native declaration : headers\openvr_capi.h:274</i> */
+		public static final int ETrackedDeviceProperty_Prop_LensCenterLeftU_Float = 2022;
+		/** <i>native declaration : headers\openvr_capi.h:275</i> */
+		public static final int ETrackedDeviceProperty_Prop_LensCenterLeftV_Float = 2023;
+		/** <i>native declaration : headers\openvr_capi.h:276</i> */
+		public static final int ETrackedDeviceProperty_Prop_LensCenterRightU_Float = 2024;
+		/** <i>native declaration : headers\openvr_capi.h:277</i> */
+		public static final int ETrackedDeviceProperty_Prop_LensCenterRightV_Float = 2025;
+		/** <i>native declaration : headers\openvr_capi.h:278</i> */
+		public static final int ETrackedDeviceProperty_Prop_UserHeadToEyeDepthMeters_Float = 2026;
+		/** <i>native declaration : headers\openvr_capi.h:279</i> */
+		public static final int ETrackedDeviceProperty_Prop_CameraFirmwareVersion_Uint64 = 2027;
+		/** <i>native declaration : headers\openvr_capi.h:280</i> */
+		public static final int ETrackedDeviceProperty_Prop_CameraFirmwareDescription_String = 2028;
+		/** <i>native declaration : headers\openvr_capi.h:281</i> */
+		public static final int ETrackedDeviceProperty_Prop_DisplayFPGAVersion_Uint64 = 2029;
+		/** <i>native declaration : headers\openvr_capi.h:282</i> */
+		public static final int ETrackedDeviceProperty_Prop_DisplayBootloaderVersion_Uint64 = 2030;
+		/** <i>native declaration : headers\openvr_capi.h:283</i> */
+		public static final int ETrackedDeviceProperty_Prop_DisplayHardwareVersion_Uint64 = 2031;
+		/** <i>native declaration : headers\openvr_capi.h:284</i> */
+		public static final int ETrackedDeviceProperty_Prop_AudioFirmwareVersion_Uint64 = 2032;
+		/** <i>native declaration : headers\openvr_capi.h:285</i> */
+		public static final int ETrackedDeviceProperty_Prop_CameraCompatibilityMode_Int32 = 2033;
+		/** <i>native declaration : headers\openvr_capi.h:286</i> */
+		public static final int ETrackedDeviceProperty_Prop_ScreenshotHorizontalFieldOfViewDegrees_Float = 2034;
+		/** <i>native declaration : headers\openvr_capi.h:287</i> */
+		public static final int ETrackedDeviceProperty_Prop_ScreenshotVerticalFieldOfViewDegrees_Float = 2035;
+		/** <i>native declaration : headers\openvr_capi.h:288</i> */
+		public static final int ETrackedDeviceProperty_Prop_DisplaySuppressed_Bool = 2036;
+		/** <i>native declaration : headers\openvr_capi.h:289</i> */
+		public static final int ETrackedDeviceProperty_Prop_DisplayAllowNightMode_Bool = 2037;
+		/** <i>native declaration : headers\openvr_capi.h:290</i> */
+		public static final int ETrackedDeviceProperty_Prop_DisplayMCImageWidth_Int32 = 2038;
+		/** <i>native declaration : headers\openvr_capi.h:291</i> */
+		public static final int ETrackedDeviceProperty_Prop_DisplayMCImageHeight_Int32 = 2039;
+		/** <i>native declaration : headers\openvr_capi.h:292</i> */
+		public static final int ETrackedDeviceProperty_Prop_DisplayMCImageNumChannels_Int32 = 2040;
+		/** <i>native declaration : headers\openvr_capi.h:293</i> */
+		public static final int ETrackedDeviceProperty_Prop_DisplayMCImageData_Binary = 2041;
+		/** <i>native declaration : headers\openvr_capi.h:294</i> */
+		public static final int ETrackedDeviceProperty_Prop_UsesDriverDirectMode_Bool = 2042;
+		/** <i>native declaration : headers\openvr_capi.h:295</i> */
+		public static final int ETrackedDeviceProperty_Prop_AttachedDeviceId_String = 3000;
+		/** <i>native declaration : headers\openvr_capi.h:296</i> */
+		public static final int ETrackedDeviceProperty_Prop_SupportedButtons_Uint64 = 3001;
+		/** <i>native declaration : headers\openvr_capi.h:297</i> */
+		public static final int ETrackedDeviceProperty_Prop_Axis0Type_Int32 = 3002;
+		/** <i>native declaration : headers\openvr_capi.h:298</i> */
+		public static final int ETrackedDeviceProperty_Prop_Axis1Type_Int32 = 3003;
+		/** <i>native declaration : headers\openvr_capi.h:299</i> */
+		public static final int ETrackedDeviceProperty_Prop_Axis2Type_Int32 = 3004;
+		/** <i>native declaration : headers\openvr_capi.h:300</i> */
+		public static final int ETrackedDeviceProperty_Prop_Axis3Type_Int32 = 3005;
+		/** <i>native declaration : headers\openvr_capi.h:301</i> */
+		public static final int ETrackedDeviceProperty_Prop_Axis4Type_Int32 = 3006;
+		/** <i>native declaration : headers\openvr_capi.h:302</i> */
+		public static final int ETrackedDeviceProperty_Prop_ControllerRoleHint_Int32 = 3007;
+		/** <i>native declaration : headers\openvr_capi.h:303</i> */
+		public static final int ETrackedDeviceProperty_Prop_FieldOfViewLeftDegrees_Float = 4000;
+		/** <i>native declaration : headers\openvr_capi.h:304</i> */
+		public static final int ETrackedDeviceProperty_Prop_FieldOfViewRightDegrees_Float = 4001;
+		/** <i>native declaration : headers\openvr_capi.h:305</i> */
+		public static final int ETrackedDeviceProperty_Prop_FieldOfViewTopDegrees_Float = 4002;
+		/** <i>native declaration : headers\openvr_capi.h:306</i> */
+		public static final int ETrackedDeviceProperty_Prop_FieldOfViewBottomDegrees_Float = 4003;
+		/** <i>native declaration : headers\openvr_capi.h:307</i> */
+		public static final int ETrackedDeviceProperty_Prop_TrackingRangeMinimumMeters_Float = 4004;
+		/** <i>native declaration : headers\openvr_capi.h:308</i> */
+		public static final int ETrackedDeviceProperty_Prop_TrackingRangeMaximumMeters_Float = 4005;
+		/** <i>native declaration : headers\openvr_capi.h:309</i> */
+		public static final int ETrackedDeviceProperty_Prop_ModeLabel_String = 4006;
+		/** <i>native declaration : headers\openvr_capi.h:310</i> */
+		public static final int ETrackedDeviceProperty_Prop_IconPathName_String = 5000;
+		/** <i>native declaration : headers\openvr_capi.h:311</i> */
+		public static final int ETrackedDeviceProperty_Prop_NamedIconPathDeviceOff_String = 5001;
+		/** <i>native declaration : headers\openvr_capi.h:312</i> */
+		public static final int ETrackedDeviceProperty_Prop_NamedIconPathDeviceSearching_String = 5002;
+		/** <i>native declaration : headers\openvr_capi.h:313</i> */
+		public static final int ETrackedDeviceProperty_Prop_NamedIconPathDeviceSearchingAlert_String = 5003;
+		/** <i>native declaration : headers\openvr_capi.h:314</i> */
+		public static final int ETrackedDeviceProperty_Prop_NamedIconPathDeviceReady_String = 5004;
+		/** <i>native declaration : headers\openvr_capi.h:315</i> */
+		public static final int ETrackedDeviceProperty_Prop_NamedIconPathDeviceReadyAlert_String = 5005;
+		/** <i>native declaration : headers\openvr_capi.h:316</i> */
+		public static final int ETrackedDeviceProperty_Prop_NamedIconPathDeviceNotReady_String = 5006;
+		/** <i>native declaration : headers\openvr_capi.h:317</i> */
+		public static final int ETrackedDeviceProperty_Prop_NamedIconPathDeviceStandby_String = 5007;
+		/** <i>native declaration : headers\openvr_capi.h:318</i> */
+		public static final int ETrackedDeviceProperty_Prop_NamedIconPathDeviceAlertLow_String = 5008;
+		/** <i>native declaration : headers\openvr_capi.h:319</i> */
+		public static final int ETrackedDeviceProperty_Prop_DisplayHiddenArea_Binary_Start = 5100;
+		/** <i>native declaration : headers\openvr_capi.h:320</i> */
+		public static final int ETrackedDeviceProperty_Prop_DisplayHiddenArea_Binary_End = 5150;
+		/** <i>native declaration : headers\openvr_capi.h:321</i> */
+		public static final int ETrackedDeviceProperty_Prop_UserConfigPath_String = 6000;
+		/** <i>native declaration : headers\openvr_capi.h:322</i> */
+		public static final int ETrackedDeviceProperty_Prop_InstallPath_String = 6001;
+		/** <i>native declaration : headers\openvr_capi.h:323</i> */
+		public static final int ETrackedDeviceProperty_Prop_VendorSpecific_Reserved_Start = 10000;
+		/** <i>native declaration : headers\openvr_capi.h:324</i> */
+		public static final int ETrackedDeviceProperty_Prop_VendorSpecific_Reserved_End = 10999;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:339</i><br>
+	 * enum values
+	 */
+	public static interface ETrackedPropertyError {
+		/** <i>native declaration : headers\openvr_capi.h:327</i> */
+		public static final int ETrackedPropertyError_TrackedProp_Success = 0;
+		/** <i>native declaration : headers\openvr_capi.h:328</i> */
+		public static final int ETrackedPropertyError_TrackedProp_WrongDataType = 1;
+		/** <i>native declaration : headers\openvr_capi.h:329</i> */
+		public static final int ETrackedPropertyError_TrackedProp_WrongDeviceClass = 2;
+		/** <i>native declaration : headers\openvr_capi.h:330</i> */
+		public static final int ETrackedPropertyError_TrackedProp_BufferTooSmall = 3;
+		/** <i>native declaration : headers\openvr_capi.h:331</i> */
+		public static final int ETrackedPropertyError_TrackedProp_UnknownProperty = 4;
+		/** <i>native declaration : headers\openvr_capi.h:332</i> */
+		public static final int ETrackedPropertyError_TrackedProp_InvalidDevice = 5;
+		/** <i>native declaration : headers\openvr_capi.h:333</i> */
+		public static final int ETrackedPropertyError_TrackedProp_CouldNotContactServer = 6;
+		/** <i>native declaration : headers\openvr_capi.h:334</i> */
+		public static final int ETrackedPropertyError_TrackedProp_ValueNotProvidedByDevice = 7;
+		/** <i>native declaration : headers\openvr_capi.h:335</i> */
+		public static final int ETrackedPropertyError_TrackedProp_StringExceedsMaximumLength = 8;
+		/** <i>native declaration : headers\openvr_capi.h:336</i> */
+		public static final int ETrackedPropertyError_TrackedProp_NotYetAvailable = 9;
+		/** <i>native declaration : headers\openvr_capi.h:337</i> */
+		public static final int ETrackedPropertyError_TrackedProp_PermissionDenied = 10;
+		/** <i>native declaration : headers\openvr_capi.h:338</i> */
+		public static final int ETrackedPropertyError_TrackedProp_InvalidOperation = 11;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:345</i><br>
+	 * enum values
+	 */
+	public static interface EVRSubmitFlags {
+		/** <i>native declaration : headers\openvr_capi.h:341</i> */
+		public static final int EVRSubmitFlags_Submit_Default = 0;
+		/** <i>native declaration : headers\openvr_capi.h:342</i> */
+		public static final int EVRSubmitFlags_Submit_LensDistortionAlreadyApplied = 1;
+		/** <i>native declaration : headers\openvr_capi.h:343</i> */
+		public static final int EVRSubmitFlags_Submit_GlRenderBuffer = 2;
+		/** <i>native declaration : headers\openvr_capi.h:344</i> */
+		public static final int EVRSubmitFlags_Submit_Reserved = 4;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:356</i><br>
+	 * enum values
+	 */
+	public static interface EVRState {
+		/** <i>native declaration : headers\openvr_capi.h:347</i> */
+		public static final int EVRState_VRState_Undefined = -1;
+		/** <i>native declaration : headers\openvr_capi.h:348</i> */
+		public static final int EVRState_VRState_Off = 0;
+		/** <i>native declaration : headers\openvr_capi.h:349</i> */
+		public static final int EVRState_VRState_Searching = 1;
+		/** <i>native declaration : headers\openvr_capi.h:350</i> */
+		public static final int EVRState_VRState_Searching_Alert = 2;
+		/** <i>native declaration : headers\openvr_capi.h:351</i> */
+		public static final int EVRState_VRState_Ready = 3;
+		/** <i>native declaration : headers\openvr_capi.h:352</i> */
+		public static final int EVRState_VRState_Ready_Alert = 4;
+		/** <i>native declaration : headers\openvr_capi.h:353</i> */
+		public static final int EVRState_VRState_NotReady = 5;
+		/** <i>native declaration : headers\openvr_capi.h:354</i> */
+		public static final int EVRState_VRState_Standby = 6;
+		/** <i>native declaration : headers\openvr_capi.h:355</i> */
+		public static final int EVRState_VRState_Ready_Alert_Low = 7;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:467</i><br>
+	 * enum values
+	 */
+	public static interface EVREventType {
+		/** <i>native declaration : headers\openvr_capi.h:358</i> */
+		public static final int EVREventType_VREvent_None = 0;
+		/** <i>native declaration : headers\openvr_capi.h:359</i> */
+		public static final int EVREventType_VREvent_TrackedDeviceActivated = 100;
+		/** <i>native declaration : headers\openvr_capi.h:360</i> */
+		public static final int EVREventType_VREvent_TrackedDeviceDeactivated = 101;
+		/** <i>native declaration : headers\openvr_capi.h:361</i> */
+		public static final int EVREventType_VREvent_TrackedDeviceUpdated = 102;
+		/** <i>native declaration : headers\openvr_capi.h:362</i> */
+		public static final int EVREventType_VREvent_TrackedDeviceUserInteractionStarted = 103;
+		/** <i>native declaration : headers\openvr_capi.h:363</i> */
+		public static final int EVREventType_VREvent_TrackedDeviceUserInteractionEnded = 104;
+		/** <i>native declaration : headers\openvr_capi.h:364</i> */
+		public static final int EVREventType_VREvent_IpdChanged = 105;
+		/** <i>native declaration : headers\openvr_capi.h:365</i> */
+		public static final int EVREventType_VREvent_EnterStandbyMode = 106;
+		/** <i>native declaration : headers\openvr_capi.h:366</i> */
+		public static final int EVREventType_VREvent_LeaveStandbyMode = 107;
+		/** <i>native declaration : headers\openvr_capi.h:367</i> */
+		public static final int EVREventType_VREvent_TrackedDeviceRoleChanged = 108;
+		/** <i>native declaration : headers\openvr_capi.h:368</i> */
+		public static final int EVREventType_VREvent_WatchdogWakeUpRequested = 109;
+		/** <i>native declaration : headers\openvr_capi.h:369</i> */
+		public static final int EVREventType_VREvent_LensDistortionChanged = 110;
+		/** <i>native declaration : headers\openvr_capi.h:370</i> */
+		public static final int EVREventType_VREvent_PropertyChanged = 111;
+		/** <i>native declaration : headers\openvr_capi.h:371</i> */
+		public static final int EVREventType_VREvent_ButtonPress = 200;
+		/** <i>native declaration : headers\openvr_capi.h:372</i> */
+		public static final int EVREventType_VREvent_ButtonUnpress = 201;
+		/** <i>native declaration : headers\openvr_capi.h:373</i> */
+		public static final int EVREventType_VREvent_ButtonTouch = 202;
+		/** <i>native declaration : headers\openvr_capi.h:374</i> */
+		public static final int EVREventType_VREvent_ButtonUntouch = 203;
+		/** <i>native declaration : headers\openvr_capi.h:375</i> */
+		public static final int EVREventType_VREvent_MouseMove = 300;
+		/** <i>native declaration : headers\openvr_capi.h:376</i> */
+		public static final int EVREventType_VREvent_MouseButtonDown = 301;
+		/** <i>native declaration : headers\openvr_capi.h:377</i> */
+		public static final int EVREventType_VREvent_MouseButtonUp = 302;
+		/** <i>native declaration : headers\openvr_capi.h:378</i> */
+		public static final int EVREventType_VREvent_FocusEnter = 303;
+		/** <i>native declaration : headers\openvr_capi.h:379</i> */
+		public static final int EVREventType_VREvent_FocusLeave = 304;
+		/** <i>native declaration : headers\openvr_capi.h:380</i> */
+		public static final int EVREventType_VREvent_Scroll = 305;
+		/** <i>native declaration : headers\openvr_capi.h:381</i> */
+		public static final int EVREventType_VREvent_TouchPadMove = 306;
+		/** <i>native declaration : headers\openvr_capi.h:382</i> */
+		public static final int EVREventType_VREvent_OverlayFocusChanged = 307;
+		/** <i>native declaration : headers\openvr_capi.h:383</i> */
+		public static final int EVREventType_VREvent_InputFocusCaptured = 400;
+		/** <i>native declaration : headers\openvr_capi.h:384</i> */
+		public static final int EVREventType_VREvent_InputFocusReleased = 401;
+		/** <i>native declaration : headers\openvr_capi.h:385</i> */
+		public static final int EVREventType_VREvent_SceneFocusLost = 402;
+		/** <i>native declaration : headers\openvr_capi.h:386</i> */
+		public static final int EVREventType_VREvent_SceneFocusGained = 403;
+		/** <i>native declaration : headers\openvr_capi.h:387</i> */
+		public static final int EVREventType_VREvent_SceneApplicationChanged = 404;
+		/** <i>native declaration : headers\openvr_capi.h:388</i> */
+		public static final int EVREventType_VREvent_SceneFocusChanged = 405;
+		/** <i>native declaration : headers\openvr_capi.h:389</i> */
+		public static final int EVREventType_VREvent_InputFocusChanged = 406;
+		/** <i>native declaration : headers\openvr_capi.h:390</i> */
+		public static final int EVREventType_VREvent_SceneApplicationSecondaryRenderingStarted = 407;
+		/** <i>native declaration : headers\openvr_capi.h:391</i> */
+		public static final int EVREventType_VREvent_HideRenderModels = 410;
+		/** <i>native declaration : headers\openvr_capi.h:392</i> */
+		public static final int EVREventType_VREvent_ShowRenderModels = 411;
+		/** <i>native declaration : headers\openvr_capi.h:393</i> */
+		public static final int EVREventType_VREvent_OverlayShown = 500;
+		/** <i>native declaration : headers\openvr_capi.h:394</i> */
+		public static final int EVREventType_VREvent_OverlayHidden = 501;
+		/** <i>native declaration : headers\openvr_capi.h:395</i> */
+		public static final int EVREventType_VREvent_DashboardActivated = 502;
+		/** <i>native declaration : headers\openvr_capi.h:396</i> */
+		public static final int EVREventType_VREvent_DashboardDeactivated = 503;
+		/** <i>native declaration : headers\openvr_capi.h:397</i> */
+		public static final int EVREventType_VREvent_DashboardThumbSelected = 504;
+		/** <i>native declaration : headers\openvr_capi.h:398</i> */
+		public static final int EVREventType_VREvent_DashboardRequested = 505;
+		/** <i>native declaration : headers\openvr_capi.h:399</i> */
+		public static final int EVREventType_VREvent_ResetDashboard = 506;
+		/** <i>native declaration : headers\openvr_capi.h:400</i> */
+		public static final int EVREventType_VREvent_RenderToast = 507;
+		/** <i>native declaration : headers\openvr_capi.h:401</i> */
+		public static final int EVREventType_VREvent_ImageLoaded = 508;
+		/** <i>native declaration : headers\openvr_capi.h:402</i> */
+		public static final int EVREventType_VREvent_ShowKeyboard = 509;
+		/** <i>native declaration : headers\openvr_capi.h:403</i> */
+		public static final int EVREventType_VREvent_HideKeyboard = 510;
+		/** <i>native declaration : headers\openvr_capi.h:404</i> */
+		public static final int EVREventType_VREvent_OverlayGamepadFocusGained = 511;
+		/** <i>native declaration : headers\openvr_capi.h:405</i> */
+		public static final int EVREventType_VREvent_OverlayGamepadFocusLost = 512;
+		/** <i>native declaration : headers\openvr_capi.h:406</i> */
+		public static final int EVREventType_VREvent_OverlaySharedTextureChanged = 513;
+		/** <i>native declaration : headers\openvr_capi.h:407</i> */
+		public static final int EVREventType_VREvent_DashboardGuideButtonDown = 514;
+		/** <i>native declaration : headers\openvr_capi.h:408</i> */
+		public static final int EVREventType_VREvent_DashboardGuideButtonUp = 515;
+		/** <i>native declaration : headers\openvr_capi.h:409</i> */
+		public static final int EVREventType_VREvent_ScreenshotTriggered = 516;
+		/** <i>native declaration : headers\openvr_capi.h:410</i> */
+		public static final int EVREventType_VREvent_ImageFailed = 517;
+		/** <i>native declaration : headers\openvr_capi.h:411</i> */
+		public static final int EVREventType_VREvent_DashboardOverlayCreated = 518;
+		/** <i>native declaration : headers\openvr_capi.h:412</i> */
+		public static final int EVREventType_VREvent_RequestScreenshot = 520;
+		/** <i>native declaration : headers\openvr_capi.h:413</i> */
+		public static final int EVREventType_VREvent_ScreenshotTaken = 521;
+		/** <i>native declaration : headers\openvr_capi.h:414</i> */
+		public static final int EVREventType_VREvent_ScreenshotFailed = 522;
+		/** <i>native declaration : headers\openvr_capi.h:415</i> */
+		public static final int EVREventType_VREvent_SubmitScreenshotToDashboard = 523;
+		/** <i>native declaration : headers\openvr_capi.h:416</i> */
+		public static final int EVREventType_VREvent_ScreenshotProgressToDashboard = 524;
+		/** <i>native declaration : headers\openvr_capi.h:417</i> */
+		public static final int EVREventType_VREvent_PrimaryDashboardDeviceChanged = 525;
+		/** <i>native declaration : headers\openvr_capi.h:418</i> */
+		public static final int EVREventType_VREvent_Notification_Shown = 600;
+		/** <i>native declaration : headers\openvr_capi.h:419</i> */
+		public static final int EVREventType_VREvent_Notification_Hidden = 601;
+		/** <i>native declaration : headers\openvr_capi.h:420</i> */
+		public static final int EVREventType_VREvent_Notification_BeginInteraction = 602;
+		/** <i>native declaration : headers\openvr_capi.h:421</i> */
+		public static final int EVREventType_VREvent_Notification_Destroyed = 603;
+		/** <i>native declaration : headers\openvr_capi.h:422</i> */
+		public static final int EVREventType_VREvent_Quit = 700;
+		/** <i>native declaration : headers\openvr_capi.h:423</i> */
+		public static final int EVREventType_VREvent_ProcessQuit = 701;
+		/** <i>native declaration : headers\openvr_capi.h:424</i> */
+		public static final int EVREventType_VREvent_QuitAborted_UserPrompt = 702;
+		/** <i>native declaration : headers\openvr_capi.h:425</i> */
+		public static final int EVREventType_VREvent_QuitAcknowledged = 703;
+		/** <i>native declaration : headers\openvr_capi.h:426</i> */
+		public static final int EVREventType_VREvent_DriverRequestedQuit = 704;
+		/** <i>native declaration : headers\openvr_capi.h:427</i> */
+		public static final int EVREventType_VREvent_ChaperoneDataHasChanged = 800;
+		/** <i>native declaration : headers\openvr_capi.h:428</i> */
+		public static final int EVREventType_VREvent_ChaperoneUniverseHasChanged = 801;
+		/** <i>native declaration : headers\openvr_capi.h:429</i> */
+		public static final int EVREventType_VREvent_ChaperoneTempDataHasChanged = 802;
+		/** <i>native declaration : headers\openvr_capi.h:430</i> */
+		public static final int EVREventType_VREvent_ChaperoneSettingsHaveChanged = 803;
+		/** <i>native declaration : headers\openvr_capi.h:431</i> */
+		public static final int EVREventType_VREvent_SeatedZeroPoseReset = 804;
+		/** <i>native declaration : headers\openvr_capi.h:432</i> */
+		public static final int EVREventType_VREvent_AudioSettingsHaveChanged = 820;
+		/** <i>native declaration : headers\openvr_capi.h:433</i> */
+		public static final int EVREventType_VREvent_BackgroundSettingHasChanged = 850;
+		/** <i>native declaration : headers\openvr_capi.h:434</i> */
+		public static final int EVREventType_VREvent_CameraSettingsHaveChanged = 851;
+		/** <i>native declaration : headers\openvr_capi.h:435</i> */
+		public static final int EVREventType_VREvent_ReprojectionSettingHasChanged = 852;
+		/** <i>native declaration : headers\openvr_capi.h:436</i> */
+		public static final int EVREventType_VREvent_ModelSkinSettingsHaveChanged = 853;
+		/** <i>native declaration : headers\openvr_capi.h:437</i> */
+		public static final int EVREventType_VREvent_EnvironmentSettingsHaveChanged = 854;
+		/** <i>native declaration : headers\openvr_capi.h:438</i> */
+		public static final int EVREventType_VREvent_PowerSettingsHaveChanged = 855;
+		/** <i>native declaration : headers\openvr_capi.h:439</i> */
+		public static final int EVREventType_VREvent_StatusUpdate = 900;
+		/** <i>native declaration : headers\openvr_capi.h:440</i> */
+		public static final int EVREventType_VREvent_MCImageUpdated = 1000;
+		/** <i>native declaration : headers\openvr_capi.h:441</i> */
+		public static final int EVREventType_VREvent_FirmwareUpdateStarted = 1100;
+		/** <i>native declaration : headers\openvr_capi.h:442</i> */
+		public static final int EVREventType_VREvent_FirmwareUpdateFinished = 1101;
+		/** <i>native declaration : headers\openvr_capi.h:443</i> */
+		public static final int EVREventType_VREvent_KeyboardClosed = 1200;
+		/** <i>native declaration : headers\openvr_capi.h:444</i> */
+		public static final int EVREventType_VREvent_KeyboardCharInput = 1201;
+		/** <i>native declaration : headers\openvr_capi.h:445</i> */
+		public static final int EVREventType_VREvent_KeyboardDone = 1202;
+		/** <i>native declaration : headers\openvr_capi.h:446</i> */
+		public static final int EVREventType_VREvent_ApplicationTransitionStarted = 1300;
+		/** <i>native declaration : headers\openvr_capi.h:447</i> */
+		public static final int EVREventType_VREvent_ApplicationTransitionAborted = 1301;
+		/** <i>native declaration : headers\openvr_capi.h:448</i> */
+		public static final int EVREventType_VREvent_ApplicationTransitionNewAppStarted = 1302;
+		/** <i>native declaration : headers\openvr_capi.h:449</i> */
+		public static final int EVREventType_VREvent_ApplicationListUpdated = 1303;
+		/** <i>native declaration : headers\openvr_capi.h:450</i> */
+		public static final int EVREventType_VREvent_ApplicationMimeTypeLoad = 1304;
+		/** <i>native declaration : headers\openvr_capi.h:451</i> */
+		public static final int EVREventType_VREvent_ApplicationTransitionNewAppLaunchComplete = 1305;
+		/** <i>native declaration : headers\openvr_capi.h:452</i> */
+		public static final int EVREventType_VREvent_Compositor_MirrorWindowShown = 1400;
+		/** <i>native declaration : headers\openvr_capi.h:453</i> */
+		public static final int EVREventType_VREvent_Compositor_MirrorWindowHidden = 1401;
+		/** <i>native declaration : headers\openvr_capi.h:454</i> */
+		public static final int EVREventType_VREvent_Compositor_ChaperoneBoundsShown = 1410;
+		/** <i>native declaration : headers\openvr_capi.h:455</i> */
+		public static final int EVREventType_VREvent_Compositor_ChaperoneBoundsHidden = 1411;
+		/** <i>native declaration : headers\openvr_capi.h:456</i> */
+		public static final int EVREventType_VREvent_TrackedCamera_StartVideoStream = 1500;
+		/** <i>native declaration : headers\openvr_capi.h:457</i> */
+		public static final int EVREventType_VREvent_TrackedCamera_StopVideoStream = 1501;
+		/** <i>native declaration : headers\openvr_capi.h:458</i> */
+		public static final int EVREventType_VREvent_TrackedCamera_PauseVideoStream = 1502;
+		/** <i>native declaration : headers\openvr_capi.h:459</i> */
+		public static final int EVREventType_VREvent_TrackedCamera_ResumeVideoStream = 1503;
+		/** <i>native declaration : headers\openvr_capi.h:460</i> */
+		public static final int EVREventType_VREvent_TrackedCamera_EditingSurface = 1550;
+		/** <i>native declaration : headers\openvr_capi.h:461</i> */
+		public static final int EVREventType_VREvent_PerformanceTest_EnableCapture = 1600;
+		/** <i>native declaration : headers\openvr_capi.h:462</i> */
+		public static final int EVREventType_VREvent_PerformanceTest_DisableCapture = 1601;
+		/** <i>native declaration : headers\openvr_capi.h:463</i> */
+		public static final int EVREventType_VREvent_PerformanceTest_FidelityLevel = 1602;
+		/** <i>native declaration : headers\openvr_capi.h:464</i> */
+		public static final int EVREventType_VREvent_MessageOverlay_Closed = 1650;
+		/** <i>native declaration : headers\openvr_capi.h:465</i> */
+		public static final int EVREventType_VREvent_VendorSpecific_Reserved_Start = 10000;
+		/** <i>native declaration : headers\openvr_capi.h:466</i> */
+		public static final int EVREventType_VREvent_VendorSpecific_Reserved_End = 19999;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:474</i><br>
+	 * enum values
+	 */
+	public static interface EDeviceActivityLevel {
+		/** <i>native declaration : headers\openvr_capi.h:469</i> */
+		public static final int EDeviceActivityLevel_k_EDeviceActivityLevel_Unknown = -1;
+		/** <i>native declaration : headers\openvr_capi.h:470</i> */
+		public static final int EDeviceActivityLevel_k_EDeviceActivityLevel_Idle = 0;
+		/** <i>native declaration : headers\openvr_capi.h:471</i> */
+		public static final int EDeviceActivityLevel_k_EDeviceActivityLevel_UserInteraction = 1;
+		/** <i>native declaration : headers\openvr_capi.h:472</i> */
+		public static final int EDeviceActivityLevel_k_EDeviceActivityLevel_UserInteraction_Timeout = 2;
+		/** <i>native declaration : headers\openvr_capi.h:473</i> */
+		public static final int EDeviceActivityLevel_k_EDeviceActivityLevel_Standby = 3;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:494</i><br>
+	 * enum values
+	 */
+	public static interface EVRButtonId {
+		/** <i>native declaration : headers\openvr_capi.h:476</i> */
+		public static final int EVRButtonId_k_EButton_System = 0;
+		/** <i>native declaration : headers\openvr_capi.h:477</i> */
+		public static final int EVRButtonId_k_EButton_ApplicationMenu = 1;
+		/** <i>native declaration : headers\openvr_capi.h:478</i> */
+		public static final int EVRButtonId_k_EButton_Grip = 2;
+		/** <i>native declaration : headers\openvr_capi.h:479</i> */
+		public static final int EVRButtonId_k_EButton_DPad_Left = 3;
+		/** <i>native declaration : headers\openvr_capi.h:480</i> */
+		public static final int EVRButtonId_k_EButton_DPad_Up = 4;
+		/** <i>native declaration : headers\openvr_capi.h:481</i> */
+		public static final int EVRButtonId_k_EButton_DPad_Right = 5;
+		/** <i>native declaration : headers\openvr_capi.h:482</i> */
+		public static final int EVRButtonId_k_EButton_DPad_Down = 6;
+		/** <i>native declaration : headers\openvr_capi.h:483</i> */
+		public static final int EVRButtonId_k_EButton_A = 7;
+		/** <i>native declaration : headers\openvr_capi.h:484</i> */
+		public static final int EVRButtonId_k_EButton_ProximitySensor = 31;
+		/** <i>native declaration : headers\openvr_capi.h:485</i> */
+		public static final int EVRButtonId_k_EButton_Axis0 = 32;
+		/** <i>native declaration : headers\openvr_capi.h:486</i> */
+		public static final int EVRButtonId_k_EButton_Axis1 = 33;
+		/** <i>native declaration : headers\openvr_capi.h:487</i> */
+		public static final int EVRButtonId_k_EButton_Axis2 = 34;
+		/** <i>native declaration : headers\openvr_capi.h:488</i> */
+		public static final int EVRButtonId_k_EButton_Axis3 = 35;
+		/** <i>native declaration : headers\openvr_capi.h:489</i> */
+		public static final int EVRButtonId_k_EButton_Axis4 = 36;
+		/** <i>native declaration : headers\openvr_capi.h:490</i> */
+		public static final int EVRButtonId_k_EButton_SteamVR_Touchpad = 32;
+		/** <i>native declaration : headers\openvr_capi.h:491</i> */
+		public static final int EVRButtonId_k_EButton_SteamVR_Trigger = 33;
+		/** <i>native declaration : headers\openvr_capi.h:492</i> */
+		public static final int EVRButtonId_k_EButton_Dashboard_Back = 2;
+		/** <i>native declaration : headers\openvr_capi.h:493</i> */
+		public static final int EVRButtonId_k_EButton_Max = 64;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:499</i><br>
+	 * enum values
+	 */
+	public static interface EVRMouseButton {
+		/** <i>native declaration : headers\openvr_capi.h:496</i> */
+		public static final int EVRMouseButton_VRMouseButton_Left = 1;
+		/** <i>native declaration : headers\openvr_capi.h:497</i> */
+		public static final int EVRMouseButton_VRMouseButton_Right = 2;
+		/** <i>native declaration : headers\openvr_capi.h:498</i> */
+		public static final int EVRMouseButton_VRMouseButton_Middle = 4;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:505</i><br>
+	 * enum values
+	 */
+	public static interface EHiddenAreaMeshType {
+		/** <i>native declaration : headers\openvr_capi.h:501</i> */
+		public static final int EHiddenAreaMeshType_k_eHiddenAreaMesh_Standard = 0;
+		/** <i>native declaration : headers\openvr_capi.h:502</i> */
+		public static final int EHiddenAreaMeshType_k_eHiddenAreaMesh_Inverse = 1;
+		/** <i>native declaration : headers\openvr_capi.h:503</i> */
+		public static final int EHiddenAreaMeshType_k_eHiddenAreaMesh_LineLoop = 2;
+		/** <i>native declaration : headers\openvr_capi.h:504</i> */
+		public static final int EHiddenAreaMeshType_k_eHiddenAreaMesh_Max = 3;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:511</i><br>
+	 * enum values
+	 */
+	public static interface EVRControllerAxisType {
+		/** <i>native declaration : headers\openvr_capi.h:507</i> */
+		public static final int EVRControllerAxisType_k_eControllerAxis_None = 0;
+		/** <i>native declaration : headers\openvr_capi.h:508</i> */
+		public static final int EVRControllerAxisType_k_eControllerAxis_TrackPad = 1;
+		/** <i>native declaration : headers\openvr_capi.h:509</i> */
+		public static final int EVRControllerAxisType_k_eControllerAxis_Joystick = 2;
+		/** <i>native declaration : headers\openvr_capi.h:510</i> */
+		public static final int EVRControllerAxisType_k_eControllerAxis_Trigger = 3;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:515</i><br>
+	 * enum values
+	 */
+	public static interface EVRControllerEventOutputType {
+		/** <i>native declaration : headers\openvr_capi.h:513</i> */
+		public static final int EVRControllerEventOutputType_ControllerEventOutput_OSEvents = 0;
+		/** <i>native declaration : headers\openvr_capi.h:514</i> */
+		public static final int EVRControllerEventOutputType_ControllerEventOutput_VREvents = 1;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:523</i><br>
+	 * enum values
+	 */
+	public static interface ECollisionBoundsStyle {
+		/** <i>native declaration : headers\openvr_capi.h:517</i> */
+		public static final int ECollisionBoundsStyle_COLLISION_BOUNDS_STYLE_BEGINNER = 0;
+		/** <i>native declaration : headers\openvr_capi.h:518</i> */
+		public static final int ECollisionBoundsStyle_COLLISION_BOUNDS_STYLE_INTERMEDIATE = 1;
+		/** <i>native declaration : headers\openvr_capi.h:519</i> */
+		public static final int ECollisionBoundsStyle_COLLISION_BOUNDS_STYLE_SQUARES = 2;
+		/** <i>native declaration : headers\openvr_capi.h:520</i> */
+		public static final int ECollisionBoundsStyle_COLLISION_BOUNDS_STYLE_ADVANCED = 3;
+		/** <i>native declaration : headers\openvr_capi.h:521</i> */
+		public static final int ECollisionBoundsStyle_COLLISION_BOUNDS_STYLE_NONE = 4;
+		/** <i>native declaration : headers\openvr_capi.h:522</i> */
+		public static final int ECollisionBoundsStyle_COLLISION_BOUNDS_STYLE_COUNT = 5;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:546</i><br>
+	 * enum values
+	 */
+	public static interface EVROverlayError {
+		/** <i>native declaration : headers\openvr_capi.h:525</i> */
+		public static final int EVROverlayError_VROverlayError_None = 0;
+		/** <i>native declaration : headers\openvr_capi.h:526</i> */
+		public static final int EVROverlayError_VROverlayError_UnknownOverlay = 10;
+		/** <i>native declaration : headers\openvr_capi.h:527</i> */
+		public static final int EVROverlayError_VROverlayError_InvalidHandle = 11;
+		/** <i>native declaration : headers\openvr_capi.h:528</i> */
+		public static final int EVROverlayError_VROverlayError_PermissionDenied = 12;
+		/** <i>native declaration : headers\openvr_capi.h:529</i> */
+		public static final int EVROverlayError_VROverlayError_OverlayLimitExceeded = 13;
+		/** <i>native declaration : headers\openvr_capi.h:530</i> */
+		public static final int EVROverlayError_VROverlayError_WrongVisibilityType = 14;
+		/** <i>native declaration : headers\openvr_capi.h:531</i> */
+		public static final int EVROverlayError_VROverlayError_KeyTooLong = 15;
+		/** <i>native declaration : headers\openvr_capi.h:532</i> */
+		public static final int EVROverlayError_VROverlayError_NameTooLong = 16;
+		/** <i>native declaration : headers\openvr_capi.h:533</i> */
+		public static final int EVROverlayError_VROverlayError_KeyInUse = 17;
+		/** <i>native declaration : headers\openvr_capi.h:534</i> */
+		public static final int EVROverlayError_VROverlayError_WrongTransformType = 18;
+		/** <i>native declaration : headers\openvr_capi.h:535</i> */
+		public static final int EVROverlayError_VROverlayError_InvalidTrackedDevice = 19;
+		/** <i>native declaration : headers\openvr_capi.h:536</i> */
+		public static final int EVROverlayError_VROverlayError_InvalidParameter = 20;
+		/** <i>native declaration : headers\openvr_capi.h:537</i> */
+		public static final int EVROverlayError_VROverlayError_ThumbnailCantBeDestroyed = 21;
+		/** <i>native declaration : headers\openvr_capi.h:538</i> */
+		public static final int EVROverlayError_VROverlayError_ArrayTooSmall = 22;
+		/** <i>native declaration : headers\openvr_capi.h:539</i> */
+		public static final int EVROverlayError_VROverlayError_RequestFailed = 23;
+		/** <i>native declaration : headers\openvr_capi.h:540</i> */
+		public static final int EVROverlayError_VROverlayError_InvalidTexture = 24;
+		/** <i>native declaration : headers\openvr_capi.h:541</i> */
+		public static final int EVROverlayError_VROverlayError_UnableToLoadFile = 25;
+		/** <i>native declaration : headers\openvr_capi.h:542</i> */
+		public static final int EVROverlayError_VROverlayError_KeyboardAlreadyInUse = 26;
+		/** <i>native declaration : headers\openvr_capi.h:543</i> */
+		public static final int EVROverlayError_VROverlayError_NoNeighbor = 27;
+		/** <i>native declaration : headers\openvr_capi.h:544</i> */
+		public static final int EVROverlayError_VROverlayError_TooManyMaskPrimitives = 29;
+		/** <i>native declaration : headers\openvr_capi.h:545</i> */
+		public static final int EVROverlayError_VROverlayError_BadMaskPrimitive = 30;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:556</i><br>
+	 * enum values
+	 */
+	public static interface EVRApplicationType {
+		/** <i>native declaration : headers\openvr_capi.h:548</i> */
+		public static final int EVRApplicationType_VRApplication_Other = 0;
+		/** <i>native declaration : headers\openvr_capi.h:549</i> */
+		public static final int EVRApplicationType_VRApplication_Scene = 1;
+		/** <i>native declaration : headers\openvr_capi.h:550</i> */
+		public static final int EVRApplicationType_VRApplication_Overlay = 2;
+		/** <i>native declaration : headers\openvr_capi.h:551</i> */
+		public static final int EVRApplicationType_VRApplication_Background = 3;
+		/** <i>native declaration : headers\openvr_capi.h:552</i> */
+		public static final int EVRApplicationType_VRApplication_Utility = 4;
+		/** <i>native declaration : headers\openvr_capi.h:553</i> */
+		public static final int EVRApplicationType_VRApplication_VRMonitor = 5;
+		/** <i>native declaration : headers\openvr_capi.h:554</i> */
+		public static final int EVRApplicationType_VRApplication_SteamWatchdog = 6;
+		/** <i>native declaration : headers\openvr_capi.h:555</i> */
+		public static final int EVRApplicationType_VRApplication_Max = 7;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:561</i><br>
+	 * enum values
+	 */
+	public static interface EVRFirmwareError {
+		/** <i>native declaration : headers\openvr_capi.h:558</i> */
+		public static final int EVRFirmwareError_VRFirmwareError_None = 0;
+		/** <i>native declaration : headers\openvr_capi.h:559</i> */
+		public static final int EVRFirmwareError_VRFirmwareError_Success = 1;
+		/** <i>native declaration : headers\openvr_capi.h:560</i> */
+		public static final int EVRFirmwareError_VRFirmwareError_Fail = 2;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:568</i><br>
+	 * enum values
+	 */
+	public static interface EVRNotificationError {
+		/** <i>native declaration : headers\openvr_capi.h:563</i> */
+		public static final int EVRNotificationError_VRNotificationError_OK = 0;
+		/** <i>native declaration : headers\openvr_capi.h:564</i> */
+		public static final int EVRNotificationError_VRNotificationError_InvalidNotificationId = 100;
+		/** <i>native declaration : headers\openvr_capi.h:565</i> */
+		public static final int EVRNotificationError_VRNotificationError_NotificationQueueFull = 101;
+		/** <i>native declaration : headers\openvr_capi.h:566</i> */
+		public static final int EVRNotificationError_VRNotificationError_InvalidOverlayHandle = 102;
+		/** <i>native declaration : headers\openvr_capi.h:567</i> */
+		public static final int EVRNotificationError_VRNotificationError_SystemWithUserValueAlreadyExists = 103;
+	};
+	
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:648</i><br>
+	 * enum values
+	 */
+	public static interface EVRInitError {
+		/** <i>native declaration : headers\openvr_capi.h:570</i> */
+		public static final int EVRInitError_VRInitError_None = 0;
+		/** <i>native declaration : headers\openvr_capi.h:571</i> */
+		public static final int EVRInitError_VRInitError_Unknown = 1;
+		/** <i>native declaration : headers\openvr_capi.h:572</i> */
+		public static final int EVRInitError_VRInitError_Init_InstallationNotFound = 100;
+		/** <i>native declaration : headers\openvr_capi.h:573</i> */
+		public static final int EVRInitError_VRInitError_Init_InstallationCorrupt = 101;
+		/** <i>native declaration : headers\openvr_capi.h:574</i> */
+		public static final int EVRInitError_VRInitError_Init_VRClientDLLNotFound = 102;
+		/** <i>native declaration : headers\openvr_capi.h:575</i> */
+		public static final int EVRInitError_VRInitError_Init_FileNotFound = 103;
+		/** <i>native declaration : headers\openvr_capi.h:576</i> */
+		public static final int EVRInitError_VRInitError_Init_FactoryNotFound = 104;
+		/** <i>native declaration : headers\openvr_capi.h:577</i> */
+		public static final int EVRInitError_VRInitError_Init_InterfaceNotFound = 105;
+		/** <i>native declaration : headers\openvr_capi.h:578</i> */
+		public static final int EVRInitError_VRInitError_Init_InvalidInterface = 106;
+		/** <i>native declaration : headers\openvr_capi.h:579</i> */
+		public static final int EVRInitError_VRInitError_Init_UserConfigDirectoryInvalid = 107;
+		/** <i>native declaration : headers\openvr_capi.h:580</i> */
+		public static final int EVRInitError_VRInitError_Init_HmdNotFound = 108;
+		/** <i>native declaration : headers\openvr_capi.h:581</i> */
+		public static final int EVRInitError_VRInitError_Init_NotInitialized = 109;
+		/** <i>native declaration : headers\openvr_capi.h:582</i> */
+		public static final int EVRInitError_VRInitError_Init_PathRegistryNotFound = 110;
+		/** <i>native declaration : headers\openvr_capi.h:583</i> */
+		public static final int EVRInitError_VRInitError_Init_NoConfigPath = 111;
+		/** <i>native declaration : headers\openvr_capi.h:584</i> */
+		public static final int EVRInitError_VRInitError_Init_NoLogPath = 112;
+		/** <i>native declaration : headers\openvr_capi.h:585</i> */
+		public static final int EVRInitError_VRInitError_Init_PathRegistryNotWritable = 113;
+		/** <i>native declaration : headers\openvr_capi.h:586</i> */
+		public static final int EVRInitError_VRInitError_Init_AppInfoInitFailed = 114;
+		/** <i>native declaration : headers\openvr_capi.h:587</i> */
+		public static final int EVRInitError_VRInitError_Init_Retry = 115;
+		/** <i>native declaration : headers\openvr_capi.h:588</i> */
+		public static final int EVRInitError_VRInitError_Init_InitCanceledByUser = 116;
+		/** <i>native declaration : headers\openvr_capi.h:589</i> */
+		public static final int EVRInitError_VRInitError_Init_AnotherAppLaunching = 117;
+		/** <i>native declaration : headers\openvr_capi.h:590</i> */
+		public static final int EVRInitError_VRInitError_Init_SettingsInitFailed = 118;
+		/** <i>native declaration : headers\openvr_capi.h:591</i> */
+		public static final int EVRInitError_VRInitError_Init_ShuttingDown = 119;
+		/** <i>native declaration : headers\openvr_capi.h:592</i> */
+		public static final int EVRInitError_VRInitError_Init_TooManyObjects = 120;
+		/** <i>native declaration : headers\openvr_capi.h:593</i> */
+		public static final int EVRInitError_VRInitError_Init_NoServerForBackgroundApp = 121;
+		/** <i>native declaration : headers\openvr_capi.h:594</i> */
+		public static final int EVRInitError_VRInitError_Init_NotSupportedWithCompositor = 122;
+		/** <i>native declaration : headers\openvr_capi.h:595</i> */
+		public static final int EVRInitError_VRInitError_Init_NotAvailableToUtilityApps = 123;
+		/** <i>native declaration : headers\openvr_capi.h:596</i> */
+		public static final int EVRInitError_VRInitError_Init_Internal = 124;
+		/** <i>native declaration : headers\openvr_capi.h:597</i> */
+		public static final int EVRInitError_VRInitError_Init_HmdDriverIdIsNone = 125;
+		/** <i>native declaration : headers\openvr_capi.h:598</i> */
+		public static final int EVRInitError_VRInitError_Init_HmdNotFoundPresenceFailed = 126;
+		/** <i>native declaration : headers\openvr_capi.h:599</i> */
+		public static final int EVRInitError_VRInitError_Init_VRMonitorNotFound = 127;
+		/** <i>native declaration : headers\openvr_capi.h:600</i> */
+		public static final int EVRInitError_VRInitError_Init_VRMonitorStartupFailed = 128;
+		/** <i>native declaration : headers\openvr_capi.h:601</i> */
+		public static final int EVRInitError_VRInitError_Init_LowPowerWatchdogNotSupported = 129;
+		/** <i>native declaration : headers\openvr_capi.h:602</i> */
+		public static final int EVRInitError_VRInitError_Init_InvalidApplicationType = 130;
+		/** <i>native declaration : headers\openvr_capi.h:603</i> */
+		public static final int EVRInitError_VRInitError_Init_NotAvailableToWatchdogApps = 131;
+		/** <i>native declaration : headers\openvr_capi.h:604</i> */
+		public static final int EVRInitError_VRInitError_Init_WatchdogDisabledInSettings = 132;
+		/** <i>native declaration : headers\openvr_capi.h:605</i> */
+		public static final int EVRInitError_VRInitError_Init_VRDashboardNotFound = 133;
+		/** <i>native declaration : headers\openvr_capi.h:606</i> */
+		public static final int EVRInitError_VRInitError_Init_VRDashboardStartupFailed = 134;
+		/** <i>native declaration : headers\openvr_capi.h:607</i> */
+		public static final int EVRInitError_VRInitError_Driver_Failed = 200;
+		/** <i>native declaration : headers\openvr_capi.h:608</i> */
+		public static final int EVRInitError_VRInitError_Driver_Unknown = 201;
+		/** <i>native declaration : headers\openvr_capi.h:609</i> */
+		public static final int EVRInitError_VRInitError_Driver_HmdUnknown = 202;
+		/** <i>native declaration : headers\openvr_capi.h:610</i> */
+		public static final int EVRInitError_VRInitError_Driver_NotLoaded = 203;
+		/** <i>native declaration : headers\openvr_capi.h:611</i> */
+		public static final int EVRInitError_VRInitError_Driver_RuntimeOutOfDate = 204;
+		/** <i>native declaration : headers\openvr_capi.h:612</i> */
+		public static final int EVRInitError_VRInitError_Driver_HmdInUse = 205;
+		/** <i>native declaration : headers\openvr_capi.h:613</i> */
+		public static final int EVRInitError_VRInitError_Driver_NotCalibrated = 206;
+		/** <i>native declaration : headers\openvr_capi.h:614</i> */
+		public static final int EVRInitError_VRInitError_Driver_CalibrationInvalid = 207;
+		/** <i>native declaration : headers\openvr_capi.h:615</i> */
+		public static final int EVRInitError_VRInitError_Driver_HmdDisplayNotFound = 208;
+		/** <i>native declaration : headers\openvr_capi.h:616</i> */
+		public static final int EVRInitError_VRInitError_Driver_TrackedDeviceInterfaceUnknown = 209;
+		/** <i>native declaration : headers\openvr_capi.h:617</i> */
+		public static final int EVRInitError_VRInitError_Driver_HmdDriverIdOutOfBounds = 211;
+		/** <i>native declaration : headers\openvr_capi.h:618</i> */
+		public static final int EVRInitError_VRInitError_Driver_HmdDisplayMirrored = 212;
+		/** <i>native declaration : headers\openvr_capi.h:619</i> */
+		public static final int EVRInitError_VRInitError_IPC_ServerInitFailed = 300;
+		/** <i>native declaration : headers\openvr_capi.h:620</i> */
+		public static final int EVRInitError_VRInitError_IPC_ConnectFailed = 301;
+		/** <i>native declaration : headers\openvr_capi.h:621</i> */
+		public static final int EVRInitError_VRInitError_IPC_SharedStateInitFailed = 302;
+		/** <i>native declaration : headers\openvr_capi.h:622</i> */
+		public static final int EVRInitError_VRInitError_IPC_CompositorInitFailed = 303;
+		/** <i>native declaration : headers\openvr_capi.h:623</i> */
+		public static final int EVRInitError_VRInitError_IPC_MutexInitFailed = 304;
+		/** <i>native declaration : headers\openvr_capi.h:624</i> */
+		public static final int EVRInitError_VRInitError_IPC_Failed = 305;
+		/** <i>native declaration : headers\openvr_capi.h:625</i> */
+		public static final int EVRInitError_VRInitError_IPC_CompositorConnectFailed = 306;
+		/** <i>native declaration : headers\openvr_capi.h:626</i> */
+		public static final int EVRInitError_VRInitError_IPC_CompositorInvalidConnectResponse = 307;
+		/** <i>native declaration : headers\openvr_capi.h:627</i> */
+		public static final int EVRInitError_VRInitError_IPC_ConnectFailedAfterMultipleAttempts = 308;
+		/** <i>native declaration : headers\openvr_capi.h:628</i> */
+		public static final int EVRInitError_VRInitError_Compositor_Failed = 400;
+		/** <i>native declaration : headers\openvr_capi.h:629</i> */
+		public static final int EVRInitError_VRInitError_Compositor_D3D11HardwareRequired = 401;
+		/** <i>native declaration : headers\openvr_capi.h:630</i> */
+		public static final int EVRInitError_VRInitError_Compositor_FirmwareRequiresUpdate = 402;
+		/** <i>native declaration : headers\openvr_capi.h:631</i> */
+		public static final int EVRInitError_VRInitError_Compositor_OverlayInitFailed = 403;
+		/** <i>native declaration : headers\openvr_capi.h:632</i> */
+		public static final int EVRInitError_VRInitError_Compositor_ScreenshotsInitFailed = 404;
+		/** <i>native declaration : headers\openvr_capi.h:633</i> */
+		public static final int EVRInitError_VRInitError_VendorSpecific_UnableToConnectToOculusRuntime = 1000;
+		/** <i>native declaration : headers\openvr_capi.h:634</i> */
+		public static final int EVRInitError_VRInitError_VendorSpecific_HmdFound_CantOpenDevice = 1101;
+		/** <i>native declaration : headers\openvr_capi.h:635</i> */
+		public static final int EVRInitError_VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart = 1102;
+		/** <i>native declaration : headers\openvr_capi.h:636</i> */
+		public static final int EVRInitError_VRInitError_VendorSpecific_HmdFound_NoStoredConfig = 1103;
+		/** <i>native declaration : headers\openvr_capi.h:637</i> */
+		public static final int EVRInitError_VRInitError_VendorSpecific_HmdFound_ConfigTooBig = 1104;
+		/** <i>native declaration : headers\openvr_capi.h:638</i> */
+		public static final int EVRInitError_VRInitError_VendorSpecific_HmdFound_ConfigTooSmall = 1105;
+		/** <i>native declaration : headers\openvr_capi.h:639</i> */
+		public static final int EVRInitError_VRInitError_VendorSpecific_HmdFound_UnableToInitZLib = 1106;
+		/** <i>native declaration : headers\openvr_capi.h:640</i> */
+		public static final int EVRInitError_VRInitError_VendorSpecific_HmdFound_CantReadFirmwareVersion = 1107;
+		/** <i>native declaration : headers\openvr_capi.h:641</i> */
+		public static final int EVRInitError_VRInitError_VendorSpecific_HmdFound_UnableToSendUserDataStart = 1108;
+		/** <i>native declaration : headers\openvr_capi.h:642</i> */
+		public static final int EVRInitError_VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataStart = 1109;
+		/** <i>native declaration : headers\openvr_capi.h:643</i> */
+		public static final int EVRInitError_VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataNext = 1110;
+		/** <i>native declaration : headers\openvr_capi.h:644</i> */
+		public static final int EVRInitError_VRInitError_VendorSpecific_HmdFound_UserDataAddressRange = 1111;
+		/** <i>native declaration : headers\openvr_capi.h:645</i> */
+		public static final int EVRInitError_VRInitError_VendorSpecific_HmdFound_UserDataError = 1112;
+		/** <i>native declaration : headers\openvr_capi.h:646</i> */
+		public static final int EVRInitError_VRInitError_VendorSpecific_HmdFound_ConfigFailedSanityCheck = 1113;
+		/** <i>native declaration : headers\openvr_capi.h:647</i> */
+		public static final int EVRInitError_VRInitError_Steam_SteamInstallationNotFound = 2000;
+	};
+	
+	
+	
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:656</i><br>
+	 * enum values
+	 */
+	public static interface EVRScreenshotType {
+		/** <i>native declaration : headers\openvr_capi.h:650</i> */
+		public static final int EVRScreenshotType_VRScreenshotType_None = 0;
+		/** <i>native declaration : headers\openvr_capi.h:651</i> */
+		public static final int EVRScreenshotType_VRScreenshotType_Mono = 1;
+		/** <i>native declaration : headers\openvr_capi.h:652</i> */
+		public static final int EVRScreenshotType_VRScreenshotType_Stereo = 2;
+		/** <i>native declaration : headers\openvr_capi.h:653</i> */
+		public static final int EVRScreenshotType_VRScreenshotType_Cubemap = 3;
+		/** <i>native declaration : headers\openvr_capi.h:654</i> */
+		public static final int EVRScreenshotType_VRScreenshotType_MonoPanorama = 4;
+		/** <i>native declaration : headers\openvr_capi.h:655</i> */
+		public static final int EVRScreenshotType_VRScreenshotType_StereoPanorama = 5;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:660</i><br>
+	 * enum values
+	 */
+	public static interface EVRScreenshotPropertyFilenames {
+		/** <i>native declaration : headers\openvr_capi.h:658</i> */
+		public static final int EVRScreenshotPropertyFilenames_VRScreenshotPropertyFilenames_Preview = 0;
+		/** <i>native declaration : headers\openvr_capi.h:659</i> */
+		public static final int EVRScreenshotPropertyFilenames_VRScreenshotPropertyFilenames_VR = 1;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:679</i><br>
+	 * enum values
+	 */
+	public static interface EVRTrackedCameraError {
+		/** <i>native declaration : headers\openvr_capi.h:662</i> */
+		public static final int EVRTrackedCameraError_VRTrackedCameraError_None = 0;
+		/** <i>native declaration : headers\openvr_capi.h:663</i> */
+		public static final int EVRTrackedCameraError_VRTrackedCameraError_OperationFailed = 100;
+		/** <i>native declaration : headers\openvr_capi.h:664</i> */
+		public static final int EVRTrackedCameraError_VRTrackedCameraError_InvalidHandle = 101;
+		/** <i>native declaration : headers\openvr_capi.h:665</i> */
+		public static final int EVRTrackedCameraError_VRTrackedCameraError_InvalidFrameHeaderVersion = 102;
+		/** <i>native declaration : headers\openvr_capi.h:666</i> */
+		public static final int EVRTrackedCameraError_VRTrackedCameraError_OutOfHandles = 103;
+		/** <i>native declaration : headers\openvr_capi.h:667</i> */
+		public static final int EVRTrackedCameraError_VRTrackedCameraError_IPCFailure = 104;
+		/** <i>native declaration : headers\openvr_capi.h:668</i> */
+		public static final int EVRTrackedCameraError_VRTrackedCameraError_NotSupportedForThisDevice = 105;
+		/** <i>native declaration : headers\openvr_capi.h:669</i> */
+		public static final int EVRTrackedCameraError_VRTrackedCameraError_SharedMemoryFailure = 106;
+		/** <i>native declaration : headers\openvr_capi.h:670</i> */
+		public static final int EVRTrackedCameraError_VRTrackedCameraError_FrameBufferingFailure = 107;
+		/** <i>native declaration : headers\openvr_capi.h:671</i> */
+		public static final int EVRTrackedCameraError_VRTrackedCameraError_StreamSetupFailure = 108;
+		/** <i>native declaration : headers\openvr_capi.h:672</i> */
+		public static final int EVRTrackedCameraError_VRTrackedCameraError_InvalidGLTextureId = 109;
+		/** <i>native declaration : headers\openvr_capi.h:673</i> */
+		public static final int EVRTrackedCameraError_VRTrackedCameraError_InvalidSharedTextureHandle = 110;
+		/** <i>native declaration : headers\openvr_capi.h:674</i> */
+		public static final int EVRTrackedCameraError_VRTrackedCameraError_FailedToGetGLTextureId = 111;
+		/** <i>native declaration : headers\openvr_capi.h:675</i> */
+		public static final int EVRTrackedCameraError_VRTrackedCameraError_SharedTextureFailure = 112;
+		/** <i>native declaration : headers\openvr_capi.h:676</i> */
+		public static final int EVRTrackedCameraError_VRTrackedCameraError_NoFrameAvailable = 113;
+		/** <i>native declaration : headers\openvr_capi.h:677</i> */
+		public static final int EVRTrackedCameraError_VRTrackedCameraError_InvalidArgument = 114;
+		/** <i>native declaration : headers\openvr_capi.h:678</i> */
+		public static final int EVRTrackedCameraError_VRTrackedCameraError_InvalidFrameBufferSize = 115;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:685</i><br>
+	 * enum values
+	 */
+	public static interface EVRTrackedCameraFrameType {
+		/** <i>native declaration : headers\openvr_capi.h:681</i> */
+		public static final int EVRTrackedCameraFrameType_VRTrackedCameraFrameType_Distorted = 0;
+		/** <i>native declaration : headers\openvr_capi.h:682</i> */
+		public static final int EVRTrackedCameraFrameType_VRTrackedCameraFrameType_Undistorted = 1;
+		/** <i>native declaration : headers\openvr_capi.h:683</i> */
+		public static final int EVRTrackedCameraFrameType_VRTrackedCameraFrameType_MaximumUndistorted = 2;
+		/** <i>native declaration : headers\openvr_capi.h:684</i> */
+		public static final int EVRTrackedCameraFrameType_MAX_CAMERA_FRAME_TYPES = 3;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:707</i><br>
+	 * enum values
+	 */
+	public static interface EVRApplicationError {
+		/** <i>native declaration : headers\openvr_capi.h:687</i> */
+		public static final int EVRApplicationError_VRApplicationError_None = 0;
+		/** <i>native declaration : headers\openvr_capi.h:688</i> */
+		public static final int EVRApplicationError_VRApplicationError_AppKeyAlreadyExists = 100;
+		/** <i>native declaration : headers\openvr_capi.h:689</i> */
+		public static final int EVRApplicationError_VRApplicationError_NoManifest = 101;
+		/** <i>native declaration : headers\openvr_capi.h:690</i> */
+		public static final int EVRApplicationError_VRApplicationError_NoApplication = 102;
+		/** <i>native declaration : headers\openvr_capi.h:691</i> */
+		public static final int EVRApplicationError_VRApplicationError_InvalidIndex = 103;
+		/** <i>native declaration : headers\openvr_capi.h:692</i> */
+		public static final int EVRApplicationError_VRApplicationError_UnknownApplication = 104;
+		/** <i>native declaration : headers\openvr_capi.h:693</i> */
+		public static final int EVRApplicationError_VRApplicationError_IPCFailed = 105;
+		/** <i>native declaration : headers\openvr_capi.h:694</i> */
+		public static final int EVRApplicationError_VRApplicationError_ApplicationAlreadyRunning = 106;
+		/** <i>native declaration : headers\openvr_capi.h:695</i> */
+		public static final int EVRApplicationError_VRApplicationError_InvalidManifest = 107;
+		/** <i>native declaration : headers\openvr_capi.h:696</i> */
+		public static final int EVRApplicationError_VRApplicationError_InvalidApplication = 108;
+		/** <i>native declaration : headers\openvr_capi.h:697</i> */
+		public static final int EVRApplicationError_VRApplicationError_LaunchFailed = 109;
+		/** <i>native declaration : headers\openvr_capi.h:698</i> */
+		public static final int EVRApplicationError_VRApplicationError_ApplicationAlreadyStarting = 110;
+		/** <i>native declaration : headers\openvr_capi.h:699</i> */
+		public static final int EVRApplicationError_VRApplicationError_LaunchInProgress = 111;
+		/** <i>native declaration : headers\openvr_capi.h:700</i> */
+		public static final int EVRApplicationError_VRApplicationError_OldApplicationQuitting = 112;
+		/** <i>native declaration : headers\openvr_capi.h:701</i> */
+		public static final int EVRApplicationError_VRApplicationError_TransitionAborted = 113;
+		/** <i>native declaration : headers\openvr_capi.h:702</i> */
+		public static final int EVRApplicationError_VRApplicationError_IsTemplate = 114;
+		/** <i>native declaration : headers\openvr_capi.h:703</i> */
+		public static final int EVRApplicationError_VRApplicationError_BufferTooSmall = 200;
+		/** <i>native declaration : headers\openvr_capi.h:704</i> */
+		public static final int EVRApplicationError_VRApplicationError_PropertyNotSet = 201;
+		/** <i>native declaration : headers\openvr_capi.h:705</i> */
+		public static final int EVRApplicationError_VRApplicationError_UnknownProperty = 202;
+		/** <i>native declaration : headers\openvr_capi.h:706</i> */
+		public static final int EVRApplicationError_VRApplicationError_InvalidParameter = 203;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:724</i><br>
+	 * enum values
+	 */
+	public static interface EVRApplicationProperty {
+		/** <i>native declaration : headers\openvr_capi.h:709</i> */
+		public static final int EVRApplicationProperty_VRApplicationProperty_Name_String = 0;
+		/** <i>native declaration : headers\openvr_capi.h:710</i> */
+		public static final int EVRApplicationProperty_VRApplicationProperty_LaunchType_String = 11;
+		/** <i>native declaration : headers\openvr_capi.h:711</i> */
+		public static final int EVRApplicationProperty_VRApplicationProperty_WorkingDirectory_String = 12;
+		/** <i>native declaration : headers\openvr_capi.h:712</i> */
+		public static final int EVRApplicationProperty_VRApplicationProperty_BinaryPath_String = 13;
+		/** <i>native declaration : headers\openvr_capi.h:713</i> */
+		public static final int EVRApplicationProperty_VRApplicationProperty_Arguments_String = 14;
+		/** <i>native declaration : headers\openvr_capi.h:714</i> */
+		public static final int EVRApplicationProperty_VRApplicationProperty_URL_String = 15;
+		/** <i>native declaration : headers\openvr_capi.h:715</i> */
+		public static final int EVRApplicationProperty_VRApplicationProperty_Description_String = 50;
+		/** <i>native declaration : headers\openvr_capi.h:716</i> */
+		public static final int EVRApplicationProperty_VRApplicationProperty_NewsURL_String = 51;
+		/** <i>native declaration : headers\openvr_capi.h:717</i> */
+		public static final int EVRApplicationProperty_VRApplicationProperty_ImagePath_String = 52;
+		/** <i>native declaration : headers\openvr_capi.h:718</i> */
+		public static final int EVRApplicationProperty_VRApplicationProperty_Source_String = 53;
+		/** <i>native declaration : headers\openvr_capi.h:719</i> */
+		public static final int EVRApplicationProperty_VRApplicationProperty_IsDashboardOverlay_Bool = 60;
+		/** <i>native declaration : headers\openvr_capi.h:720</i> */
+		public static final int EVRApplicationProperty_VRApplicationProperty_IsTemplate_Bool = 61;
+		/** <i>native declaration : headers\openvr_capi.h:721</i> */
+		public static final int EVRApplicationProperty_VRApplicationProperty_IsInstanced_Bool = 62;
+		/** <i>native declaration : headers\openvr_capi.h:722</i> */
+		public static final int EVRApplicationProperty_VRApplicationProperty_IsInternal_Bool = 63;
+		/** <i>native declaration : headers\openvr_capi.h:723</i> */
+		public static final int EVRApplicationProperty_VRApplicationProperty_LastLaunchTime_Uint64 = 70;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:730</i><br>
+	 * enum values
+	 */
+	public static interface EVRApplicationTransitionState {
+		/** <i>native declaration : headers\openvr_capi.h:726</i> */
+		public static final int EVRApplicationTransitionState_VRApplicationTransition_None = 0;
+		/** <i>native declaration : headers\openvr_capi.h:727</i> */
+		public static final int EVRApplicationTransitionState_VRApplicationTransition_OldAppQuitSent = 10;
+		/** <i>native declaration : headers\openvr_capi.h:728</i> */
+		public static final int EVRApplicationTransitionState_VRApplicationTransition_WaitingForExternalLaunch = 11;
+		/** <i>native declaration : headers\openvr_capi.h:729</i> */
+		public static final int EVRApplicationTransitionState_VRApplicationTransition_NewAppLaunched = 20;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:742</i><br>
+	 * enum values
+	 */
+	public static interface ChaperoneCalibrationState {
+		/** <i>native declaration : headers\openvr_capi.h:732</i> */
+		public static final int ChaperoneCalibrationState_OK = 1;
+		/** <i>native declaration : headers\openvr_capi.h:733</i> */
+		public static final int ChaperoneCalibrationState_Warning = 100;
+		/** <i>native declaration : headers\openvr_capi.h:734</i> */
+		public static final int ChaperoneCalibrationState_Warning_BaseStationMayHaveMoved = 101;
+		/** <i>native declaration : headers\openvr_capi.h:735</i> */
+		public static final int ChaperoneCalibrationState_Warning_BaseStationRemoved = 102;
+		/** <i>native declaration : headers\openvr_capi.h:736</i> */
+		public static final int ChaperoneCalibrationState_Warning_SeatedBoundsInvalid = 103;
+		/** <i>native declaration : headers\openvr_capi.h:737</i> */
+		public static final int ChaperoneCalibrationState_Error = 200;
+		/** <i>native declaration : headers\openvr_capi.h:738</i> */
+		public static final int ChaperoneCalibrationState_Error_BaseStationUninitialized = 201;
+		/** <i>native declaration : headers\openvr_capi.h:739</i> */
+		public static final int ChaperoneCalibrationState_Error_BaseStationConflict = 202;
+		/** <i>native declaration : headers\openvr_capi.h:740</i> */
+		public static final int ChaperoneCalibrationState_Error_PlayAreaInvalid = 203;
+		/** <i>native declaration : headers\openvr_capi.h:741</i> */
+		public static final int ChaperoneCalibrationState_Error_CollisionBoundsInvalid = 204;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:746</i><br>
+	 * enum values
+	 */
+	public static interface EChaperoneConfigFile {
+		/** <i>native declaration : headers\openvr_capi.h:744</i> */
+		public static final int EChaperoneConfigFile_Live = 1;
+		/** <i>native declaration : headers\openvr_capi.h:745</i> */
+		public static final int EChaperoneConfigFile_Temp = 2;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:749</i><br>
+	 * enum values
+	 */
+	public static interface EChaperoneImportFlags {
+		/** <i>native declaration : headers\openvr_capi.h:748</i> */
+		public static final int EChaperoneImportFlags_EChaperoneImport_BoundsOnly = 1;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:762</i><br>
+	 * enum values
+	 */
+	public static interface EVRCompositorError {
+		/** <i>native declaration : headers\openvr_capi.h:751</i> */
+		public static final int EVRCompositorError_VRCompositorError_None = 0;
+		/** <i>native declaration : headers\openvr_capi.h:752</i> */
+		public static final int EVRCompositorError_VRCompositorError_RequestFailed = 1;
+		/** <i>native declaration : headers\openvr_capi.h:753</i> */
+		public static final int EVRCompositorError_VRCompositorError_IncompatibleVersion = 100;
+		/** <i>native declaration : headers\openvr_capi.h:754</i> */
+		public static final int EVRCompositorError_VRCompositorError_DoNotHaveFocus = 101;
+		/** <i>native declaration : headers\openvr_capi.h:755</i> */
+		public static final int EVRCompositorError_VRCompositorError_InvalidTexture = 102;
+		/** <i>native declaration : headers\openvr_capi.h:756</i> */
+		public static final int EVRCompositorError_VRCompositorError_IsNotSceneApplication = 103;
+		/** <i>native declaration : headers\openvr_capi.h:757</i> */
+		public static final int EVRCompositorError_VRCompositorError_TextureIsOnWrongDevice = 104;
+		/** <i>native declaration : headers\openvr_capi.h:758</i> */
+		public static final int EVRCompositorError_VRCompositorError_TextureUsesUnsupportedFormat = 105;
+		/** <i>native declaration : headers\openvr_capi.h:759</i> */
+		public static final int EVRCompositorError_VRCompositorError_SharedTexturesNotSupported = 106;
+		/** <i>native declaration : headers\openvr_capi.h:760</i> */
+		public static final int EVRCompositorError_VRCompositorError_IndexOutOfRange = 107;
+		/** <i>native declaration : headers\openvr_capi.h:761</i> */
+		public static final int EVRCompositorError_VRCompositorError_AlreadySubmitted = 108;
+	};
+	
+	
+	
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:766</i><br>
+	 * enum values
+	 */
+	public static interface VROverlayInputMethod {
+		/** <i>native declaration : headers\openvr_capi.h:764</i> */
+		public static final int VROverlayInputMethod_None = 0;
+		/** <i>native declaration : headers\openvr_capi.h:765</i> */
+		public static final int VROverlayInputMethod_Mouse = 1;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:772</i><br>
+	 * enum values
+	 */
+	public static interface VROverlayTransformType {
+		/** <i>native declaration : headers\openvr_capi.h:768</i> */
+		public static final int VROverlayTransformType_VROverlayTransform_Absolute = 0;
+		/** <i>native declaration : headers\openvr_capi.h:769</i> */
+		public static final int VROverlayTransformType_VROverlayTransform_TrackedDeviceRelative = 1;
+		/** <i>native declaration : headers\openvr_capi.h:770</i> */
+		public static final int VROverlayTransformType_VROverlayTransform_SystemOverlay = 2;
+		/** <i>native declaration : headers\openvr_capi.h:771</i> */
+		public static final int VROverlayTransformType_VROverlayTransform_TrackedComponent = 3;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:790</i><br>
+	 * enum values
+	 */
+	public static interface VROverlayFlags {
+		/** <i>native declaration : headers\openvr_capi.h:774</i> */
+		public static final int VROverlayFlags_None = 0;
+		/** <i>native declaration : headers\openvr_capi.h:775</i> */
+		public static final int VROverlayFlags_Curved = 1;
+		/** <i>native declaration : headers\openvr_capi.h:776</i> */
+		public static final int VROverlayFlags_RGSS4X = 2;
+		/** <i>native declaration : headers\openvr_capi.h:777</i> */
+		public static final int VROverlayFlags_NoDashboardTab = 3;
+		/** <i>native declaration : headers\openvr_capi.h:778</i> */
+		public static final int VROverlayFlags_AcceptsGamepadEvents = 4;
+		/** <i>native declaration : headers\openvr_capi.h:779</i> */
+		public static final int VROverlayFlags_ShowGamepadFocus = 5;
+		/** <i>native declaration : headers\openvr_capi.h:780</i> */
+		public static final int VROverlayFlags_SendVRScrollEvents = 6;
+		/** <i>native declaration : headers\openvr_capi.h:781</i> */
+		public static final int VROverlayFlags_SendVRTouchpadEvents = 7;
+		/** <i>native declaration : headers\openvr_capi.h:782</i> */
+		public static final int VROverlayFlags_ShowTouchPadScrollWheel = 8;
+		/** <i>native declaration : headers\openvr_capi.h:783</i> */
+		public static final int VROverlayFlags_TransferOwnershipToInternalProcess = 9;
+		/** <i>native declaration : headers\openvr_capi.h:784</i> */
+		public static final int VROverlayFlags_SideBySide_Parallel = 10;
+		/** <i>native declaration : headers\openvr_capi.h:785</i> */
+		public static final int VROverlayFlags_SideBySide_Crossed = 11;
+		/** <i>native declaration : headers\openvr_capi.h:786</i> */
+		public static final int VROverlayFlags_Panorama = 12;
+		/** <i>native declaration : headers\openvr_capi.h:787</i> */
+		public static final int VROverlayFlags_StereoPanorama = 13;
+		/** <i>native declaration : headers\openvr_capi.h:788</i> */
+		public static final int VROverlayFlags_SortWithNonSceneOverlays = 14;
+		/** <i>native declaration : headers\openvr_capi.h:789</i> */
+		public static final int VROverlayFlags_VisibleInDashboard = 15;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:799</i><br>
+	 * enum values
+	 */
+	public static interface VRMessageOverlayResponse {
+		/** <i>native declaration : headers\openvr_capi.h:792</i> */
+		public static final int VRMessageOverlayResponse_ButtonPress_0 = 0;
+		/** <i>native declaration : headers\openvr_capi.h:793</i> */
+		public static final int VRMessageOverlayResponse_ButtonPress_1 = 1;
+		/** <i>native declaration : headers\openvr_capi.h:794</i> */
+		public static final int VRMessageOverlayResponse_ButtonPress_2 = 2;
+		/** <i>native declaration : headers\openvr_capi.h:795</i> */
+		public static final int VRMessageOverlayResponse_ButtonPress_3 = 3;
+		/** <i>native declaration : headers\openvr_capi.h:796</i> */
+		public static final int VRMessageOverlayResponse_CouldntFindSystemOverlay = 4;
+		/** <i>native declaration : headers\openvr_capi.h:797</i> */
+		public static final int VRMessageOverlayResponse_CouldntFindOrCreateClientOverlay = 5;
+		/** <i>native declaration : headers\openvr_capi.h:798</i> */
+		public static final int VRMessageOverlayResponse_ApplicationQuit = 6;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:804</i><br>
+	 * enum values
+	 */
+	public static interface EGamepadTextInputMode {
+		/** <i>native declaration : headers\openvr_capi.h:801</i> */
+		public static final int EGamepadTextInputMode_k_EGamepadTextInputModeNormal = 0;
+		/** <i>native declaration : headers\openvr_capi.h:802</i> */
+		public static final int EGamepadTextInputMode_k_EGamepadTextInputModePassword = 1;
+		/** <i>native declaration : headers\openvr_capi.h:803</i> */
+		public static final int EGamepadTextInputMode_k_EGamepadTextInputModeSubmit = 2;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:808</i><br>
+	 * enum values
+	 */
+	public static interface EGamepadTextInputLineMode {
+		/** <i>native declaration : headers\openvr_capi.h:806</i> */
+		public static final int EGamepadTextInputLineMode_k_EGamepadTextInputLineModeSingleLine = 0;
+		/** <i>native declaration : headers\openvr_capi.h:807</i> */
+		public static final int EGamepadTextInputLineMode_k_EGamepadTextInputLineModeMultipleLines = 1;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:815</i><br>
+	 * enum values
+	 */
+	public static interface EOverlayDirection {
+		/** <i>native declaration : headers\openvr_capi.h:810</i> */
+		public static final int EOverlayDirection_OverlayDirection_Up = 0;
+		/** <i>native declaration : headers\openvr_capi.h:811</i> */
+		public static final int EOverlayDirection_OverlayDirection_Down = 1;
+		/** <i>native declaration : headers\openvr_capi.h:812</i> */
+		public static final int EOverlayDirection_OverlayDirection_Left = 2;
+		/** <i>native declaration : headers\openvr_capi.h:813</i> */
+		public static final int EOverlayDirection_OverlayDirection_Right = 3;
+		/** <i>native declaration : headers\openvr_capi.h:814</i> */
+		public static final int EOverlayDirection_OverlayDirection_Count = 4;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:819</i><br>
+	 * enum values
+	 */
+	public static interface EVROverlayIntersectionMaskPrimitiveType {
+		/** <i>native declaration : headers\openvr_capi.h:817</i> */
+		public static final int EVROverlayIntersectionMaskPrimitiveType_OverlayIntersectionPrimitiveType_Rectangle = 0;
+		/** <i>native declaration : headers\openvr_capi.h:818</i> */
+		public static final int EVROverlayIntersectionMaskPrimitiveType_OverlayIntersectionPrimitiveType_Circle = 1;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:834</i><br>
+	 * enum values
+	 */
+	public static interface EVRRenderModelError {
+		/** <i>native declaration : headers\openvr_capi.h:821</i> */
+		public static final int EVRRenderModelError_VRRenderModelError_None = 0;
+		/** <i>native declaration : headers\openvr_capi.h:822</i> */
+		public static final int EVRRenderModelError_VRRenderModelError_Loading = 100;
+		/** <i>native declaration : headers\openvr_capi.h:823</i> */
+		public static final int EVRRenderModelError_VRRenderModelError_NotSupported = 200;
+		/** <i>native declaration : headers\openvr_capi.h:824</i> */
+		public static final int EVRRenderModelError_VRRenderModelError_InvalidArg = 300;
+		/** <i>native declaration : headers\openvr_capi.h:825</i> */
+		public static final int EVRRenderModelError_VRRenderModelError_InvalidModel = 301;
+		/** <i>native declaration : headers\openvr_capi.h:826</i> */
+		public static final int EVRRenderModelError_VRRenderModelError_NoShapes = 302;
+		/** <i>native declaration : headers\openvr_capi.h:827</i> */
+		public static final int EVRRenderModelError_VRRenderModelError_MultipleShapes = 303;
+		/** <i>native declaration : headers\openvr_capi.h:828</i> */
+		public static final int EVRRenderModelError_VRRenderModelError_TooManyVertices = 304;
+		/** <i>native declaration : headers\openvr_capi.h:829</i> */
+		public static final int EVRRenderModelError_VRRenderModelError_MultipleTextures = 305;
+		/** <i>native declaration : headers\openvr_capi.h:830</i> */
+		public static final int EVRRenderModelError_VRRenderModelError_BufferTooSmall = 306;
+		/** <i>native declaration : headers\openvr_capi.h:831</i> */
+		public static final int EVRRenderModelError_VRRenderModelError_NotEnoughNormals = 307;
+		/** <i>native declaration : headers\openvr_capi.h:832</i> */
+		public static final int EVRRenderModelError_VRRenderModelError_NotEnoughTexCoords = 308;
+		/** <i>native declaration : headers\openvr_capi.h:833</i> */
+		public static final int EVRRenderModelError_VRRenderModelError_InvalidTexture = 400;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:841</i><br>
+	 * enum values
+	 */
+	public static interface EVRComponentProperty {
+		/** <i>native declaration : headers\openvr_capi.h:836</i> */
+		public static final int EVRComponentProperty_VRComponentProperty_IsStatic = 1;
+		/** <i>native declaration : headers\openvr_capi.h:837</i> */
+		public static final int EVRComponentProperty_VRComponentProperty_IsVisible = 2;
+		/** <i>native declaration : headers\openvr_capi.h:838</i> */
+		public static final int EVRComponentProperty_VRComponentProperty_IsTouched = 4;
+		/** <i>native declaration : headers\openvr_capi.h:839</i> */
+		public static final int EVRComponentProperty_VRComponentProperty_IsPressed = 8;
+		/** <i>native declaration : headers\openvr_capi.h:840</i> */
+		public static final int EVRComponentProperty_VRComponentProperty_IsScrolled = 16;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:846</i><br>
+	 * enum values
+	 */
+	public static interface EVRNotificationType {
+		/** <i>native declaration : headers\openvr_capi.h:843</i> */
+		public static final int EVRNotificationType_Transient = 0;
+		/** <i>native declaration : headers\openvr_capi.h:844</i> */
+		public static final int EVRNotificationType_Persistent = 1;
+		/** <i>native declaration : headers\openvr_capi.h:845</i> */
+		public static final int EVRNotificationType_Transient_SystemWithUserValue = 2;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:853</i><br>
+	 * enum values
+	 */
+	public static interface EVRNotificationStyle {
+		/** <i>native declaration : headers\openvr_capi.h:848</i> */
+		public static final int EVRNotificationStyle_None = 0;
+		/** <i>native declaration : headers\openvr_capi.h:849</i> */
+		public static final int EVRNotificationStyle_Application = 100;
+		/** <i>native declaration : headers\openvr_capi.h:850</i> */
+		public static final int EVRNotificationStyle_Contact_Disabled = 200;
+		/** <i>native declaration : headers\openvr_capi.h:851</i> */
+		public static final int EVRNotificationStyle_Contact_Enabled = 201;
+		/** <i>native declaration : headers\openvr_capi.h:852</i> */
+		public static final int EVRNotificationStyle_Contact_Active = 202;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:861</i><br>
+	 * enum values
+	 */
+	public static interface EVRSettingsError {
+		/** <i>native declaration : headers\openvr_capi.h:855</i> */
+		public static final int EVRSettingsError_VRSettingsError_None = 0;
+		/** <i>native declaration : headers\openvr_capi.h:856</i> */
+		public static final int EVRSettingsError_VRSettingsError_IPCFailed = 1;
+		/** <i>native declaration : headers\openvr_capi.h:857</i> */
+		public static final int EVRSettingsError_VRSettingsError_WriteFailed = 2;
+		/** <i>native declaration : headers\openvr_capi.h:858</i> */
+		public static final int EVRSettingsError_VRSettingsError_ReadFailed = 3;
+		/** <i>native declaration : headers\openvr_capi.h:859</i> */
+		public static final int EVRSettingsError_VRSettingsError_JsonParseFailed = 4;
+		/** <i>native declaration : headers\openvr_capi.h:860</i> */
+		public static final int EVRSettingsError_VRSettingsError_UnsetSettingHasNoDefault = 5;
+	};
+	/**
+	 * <i>native declaration : headers\openvr_capi.h:869</i><br>
+	 * enum values
+	 */
+	public static interface EVRScreenshotError {
+		/** <i>native declaration : headers\openvr_capi.h:863</i> */
+		public static final int EVRScreenshotError_VRScreenshotError_None = 0;
+		/** <i>native declaration : headers\openvr_capi.h:864</i> */
+		public static final int EVRScreenshotError_VRScreenshotError_RequestFailed = 1;
+		/** <i>native declaration : headers\openvr_capi.h:865</i> */
+		public static final int EVRScreenshotError_VRScreenshotError_IncompatibleVersion = 100;
+		/** <i>native declaration : headers\openvr_capi.h:866</i> */
+		public static final int EVRScreenshotError_VRScreenshotError_NotFound = 101;
+		/** <i>native declaration : headers\openvr_capi.h:867</i> */
+		public static final int EVRScreenshotError_VRScreenshotError_BufferTooSmall = 102;
+		/** <i>native declaration : headers\openvr_capi.h:868</i> */
+		public static final int EVRScreenshotError_VRScreenshotError_ScreenshotAlreadyInProgress = 108;
+	};
+
+	/**
+	 * Global entry points<br>
+	 * Original signature : <code>intptr_t VR_InitInternal(EVRInitError*, EVRApplicationType)</code><br>
+	 * <i>native declaration : headers\openvr_capi.h:1876</i><br>
+	 */
+	public static native IntByReference VR_InitInternal(IntByReference peError, int eType);
+	/**
+	 * Global entry points<br>
+	 * Original signature : <code>intptr_t VR_InitInternal(EVRInitError*, EVRApplicationType)</code><br>
+	 * <i>native declaration : headers\openvr_capi.h:1876</i>
+	 */
+	public static native IntByReference VR_InitInternal(IntBuffer peError, int eType);
+	/**
+	 * Original signature : <code>void VR_ShutdownInternal()</code><br>
+	 * <i>native declaration : headers\openvr_capi.h:1878</i>
+	 */
+	public static native void VR_ShutdownInternal();
+	/**
+	 * Original signature : <code>bool VR_IsHmdPresent()</code><br>
+	 * <i>native declaration : headers\openvr_capi.h:1880</i>
+	 */
+	public static native byte VR_IsHmdPresent();
+	/**
+	 * Original signature : <code>intptr_t VR_GetGenericInterface(const char*, EVRInitError*)</code><br>
+	 * <i>native declaration : headers\openvr_capi.h:1882</i><br>
+	 * @deprecated use the safer methods {@link #VR_GetGenericInterface(java.lang.String, java.nio.IntBuffer)} and {@link #VR_GetGenericInterface(com.sun.jna.Pointer, com.sun.jna.ptr.IntByReference)} instead
+	 */
+	@Deprecated 
+	public static native IntByReference VR_GetGenericInterface(Pointer pchInterfaceVersion, IntByReference peError);
+	/**
+	 * Original signature : <code>intptr_t VR_GetGenericInterface(const char*, EVRInitError*)</code><br>
+	 * <i>native declaration : headers\openvr_capi.h:1882</i>
+	 */
+	public static native IntByReference VR_GetGenericInterface(String pchInterfaceVersion, IntByReference peError);
+	/**
+	 * Original signature : <code>bool VR_IsRuntimeInstalled()</code><br>
+	 * <i>native declaration : headers\openvr_capi.h:1884</i>
+	 */
+	public static native byte VR_IsRuntimeInstalled();
+	/**
+	 * Original signature : <code>char* VR_GetVRInitErrorAsSymbol(EVRInitError)</code><br>
+	 * <i>native declaration : headers\openvr_capi.h:1886</i>
+	 */
+	public static native Pointer VR_GetVRInitErrorAsSymbol(int error);
+	/**
+	 * Original signature : <code>char* VR_GetVRInitErrorAsEnglishDescription(EVRInitError)</code><br>
+	 * <i>native declaration : headers\openvr_capi.h:1888</i>
+	 */
+	public static native Pointer VR_GetVRInitErrorAsEnglishDescription(int error);
+	public static class VkQueue_T extends PointerType {
+		public VkQueue_T(Pointer address) {
+			super(address);
+		}
+		public VkQueue_T() {
+			super();
+		}
+	};
+	public static class VkPhysicalDevice_T extends PointerType {
+		public VkPhysicalDevice_T(Pointer address) {
+			super(address);
+		}
+		public VkPhysicalDevice_T() {
+			super();
+		}
+	};
+	public static class VkInstance_T extends PointerType {
+		public VkInstance_T(Pointer address) {
+			super(address);
+		}
+		public VkInstance_T() {
+			super();
+		}
+	};
+	public static class ID3D12CommandQueue extends PointerType {
+		public ID3D12CommandQueue(Pointer address) {
+			super(address);
+		}
+		public ID3D12CommandQueue() {
+			super();
+		}
+	};
+	public static class ID3D12Resource extends PointerType {
+		public ID3D12Resource(Pointer address) {
+			super(address);
+		}
+		public ID3D12Resource() {
+			super();
+		}
+	};
+	public static class VkDevice_T extends PointerType {
+		public VkDevice_T(Pointer address) {
+			super(address);
+		}
+		public VkDevice_T() {
+			super();
+		}
+	};
+}

+ 47 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/NotificationBitmap_t.java

@@ -0,0 +1,47 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1236</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class NotificationBitmap_t extends Structure {
+	/**
+	 * void *<br>
+	 * C type : void*
+	 */
+	public Pointer m_pImageData;
+	public int m_nWidth;
+	public int m_nHeight;
+	public int m_nBytesPerPixel;
+	public NotificationBitmap_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("m_pImageData", "m_nWidth", "m_nHeight", "m_nBytesPerPixel");
+	}
+	/**
+	 * @param m_pImageData void *<br>
+	 * C type : void*
+	 */
+	public NotificationBitmap_t(Pointer m_pImageData, int m_nWidth, int m_nHeight, int m_nBytesPerPixel) {
+		super();
+		this.m_pImageData = m_pImageData;
+		this.m_nWidth = m_nWidth;
+		this.m_nHeight = m_nHeight;
+		this.m_nBytesPerPixel = m_nBytesPerPixel;
+	}
+	public NotificationBitmap_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends NotificationBitmap_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends NotificationBitmap_t implements Structure.ByValue {
+		
+	};
+}

+ 778 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/OpenVRUtil.java

@@ -0,0 +1,778 @@
+package com.jme3.system.jopenvr;
+
+import com.jme3.input.vr.OpenVRInput;
+import com.jme3.system.jopenvr.JOpenVRLibrary.EColorSpace;
+import com.jme3.system.jopenvr.JOpenVRLibrary.ETextureType;
+import com.jme3.system.jopenvr.JOpenVRLibrary.ETrackedDeviceProperty;
+import com.jme3.system.jopenvr.JOpenVRLibrary.ETrackedPropertyError;
+import com.jme3.system.jopenvr.JOpenVRLibrary.EVRCompositorError;
+import com.jme3.system.jopenvr.JOpenVRLibrary.EVRInitError;
+import com.sun.jna.Memory;
+import com.sun.jna.Pointer;
+import com.sun.jna.ptr.IntByReference;
+
+/**
+ * A utility class that provide helper methods for OpenVR system.
+ * @author Julien Seinturier - (c) 2016 - JOrigin project - <a href="http://www.jorigin.org">http:/www.jorigin.org</a>
+ *
+ */
+public class OpenVRUtil {
+
+	/**
+	 * Get the value of the given string {@link JOpenVRLibrary.ETrackedDeviceProperty property} attached to the given device.
+	 * @param system the underlying OpenVR system.
+	 * @param deviceIndex the index of the device to query.
+	 * @param property the property to query.
+	 * @param bufferSize the size of the buffer to use for storing native string.
+	 * @return the value of the given string property attached to the given device.
+	 * @see OpenVRInput#getTrackedControllerCount()
+	 * @see JOpenVRLibrary.ETrackedDeviceProperty
+	 * @see #getTrackedDeviceStringProperty(VR_IVRSystem_FnTable, int, int)
+	 */
+	public static String getTrackedDeviceStringProperty(VR_IVRSystem_FnTable system, int deviceIndex, int property, int bufferSize){
+		String str ="";
+		
+		int unBufferSize = 256;
+		Pointer pchValue = new Memory(unBufferSize); 
+		IntByReference pError = new IntByReference();
+		
+		system.GetStringTrackedDeviceProperty.apply(deviceIndex, property, pchValue, unBufferSize, pError);
+		
+		if (pError.getValue() == ETrackedPropertyError.ETrackedPropertyError_TrackedProp_Success){
+			str = pchValue.getString(0);
+		} else if (pError.getValue() == ETrackedPropertyError.ETrackedPropertyError_TrackedProp_BufferTooSmall){
+			throw new IllegalArgumentException("Cannot access property \""+getETrackedDevicePropertyString(property)+"\" ("+property+") for device "+deviceIndex+": "+getETrackedPropertyErrorString(pError.getValue())+" ("+pError.getValue()+")");
+		} else if (pError.getValue() == ETrackedPropertyError.ETrackedPropertyError_TrackedProp_CouldNotContactServer){
+			throw new IllegalArgumentException("Cannot access property \""+getETrackedDevicePropertyString(property)+"\" ("+property+") for device "+deviceIndex+": "+getETrackedPropertyErrorString(pError.getValue())+" ("+pError.getValue()+")");
+		} else if (pError.getValue() == ETrackedPropertyError.ETrackedPropertyError_TrackedProp_InvalidDevice){
+			throw new IllegalArgumentException("Cannot access property \""+getETrackedDevicePropertyString(property)+"\" ("+property+") for device "+deviceIndex+": "+getETrackedPropertyErrorString(pError.getValue())+" ("+pError.getValue()+")");
+		} else if (pError.getValue() == ETrackedPropertyError.ETrackedPropertyError_TrackedProp_InvalidOperation){
+			throw new IllegalArgumentException("Cannot access property \""+getETrackedDevicePropertyString(property)+"\" ("+property+") for device "+deviceIndex+": "+getETrackedPropertyErrorString(pError.getValue())+" ("+pError.getValue()+")");
+		} else if (pError.getValue() == ETrackedPropertyError.ETrackedPropertyError_TrackedProp_NotYetAvailable){
+			throw new IllegalArgumentException("Cannot access property \""+getETrackedDevicePropertyString(property)+"\" ("+property+") for device "+deviceIndex+": "+getETrackedPropertyErrorString(pError.getValue())+" ("+pError.getValue()+")");
+		} else if (pError.getValue() == ETrackedPropertyError.ETrackedPropertyError_TrackedProp_PermissionDenied){
+			throw new IllegalArgumentException("Cannot access property \""+getETrackedDevicePropertyString(property)+"\" ("+property+") for device "+deviceIndex+": "+getETrackedPropertyErrorString(pError.getValue())+" ("+pError.getValue()+")");
+		} else if (pError.getValue() == ETrackedPropertyError.ETrackedPropertyError_TrackedProp_StringExceedsMaximumLength){
+			throw new IllegalArgumentException("Cannot access property \""+getETrackedDevicePropertyString(property)+"\" ("+property+") for device "+deviceIndex+": "+getETrackedPropertyErrorString(pError.getValue())+" ("+pError.getValue()+")");
+		} else if (pError.getValue() == ETrackedPropertyError.ETrackedPropertyError_TrackedProp_UnknownProperty){
+			throw new IllegalArgumentException("Cannot access property \""+getETrackedDevicePropertyString(property)+"\" ("+property+") for device "+deviceIndex+": "+getETrackedPropertyErrorString(pError.getValue())+" ("+pError.getValue()+")");
+		} else if (pError.getValue() == ETrackedPropertyError.ETrackedPropertyError_TrackedProp_ValueNotProvidedByDevice){
+			throw new IllegalArgumentException("Cannot access property \""+getETrackedDevicePropertyString(property)+"\" ("+property+") for device "+deviceIndex+": "+getETrackedPropertyErrorString(pError.getValue())+" ("+pError.getValue()+")");
+		} else if (pError.getValue() == ETrackedPropertyError.ETrackedPropertyError_TrackedProp_WrongDataType){
+			throw new IllegalArgumentException("Cannot access property \""+getETrackedDevicePropertyString(property)+"\" ("+property+") for device "+deviceIndex+": "+getETrackedPropertyErrorString(pError.getValue())+" ("+pError.getValue()+")");
+		} else if (pError.getValue() == ETrackedPropertyError.ETrackedPropertyError_TrackedProp_WrongDeviceClass){
+			throw new IllegalArgumentException("Cannot access property \""+getETrackedDevicePropertyString(property)+"\" ("+property+") for device "+deviceIndex+": "+getETrackedPropertyErrorString(pError.getValue())+" ("+pError.getValue()+")");
+		} else {
+			throw new IllegalArgumentException("Cannot access property \""+getETrackedDevicePropertyString(property)+"\" ("+property+") for device "+deviceIndex+": "+getETrackedPropertyErrorString(pError.getValue())+" ("+pError.getValue()+")");
+		}
+		
+		return str;
+	}
+	
+	/**
+	 * Get the value of the given string {@link JOpenVRLibrary.ETrackedDeviceProperty property} attached to the given device.
+	 * @param system the underlying OpenVR system.
+	 * @param deviceIndex the index of the device to query.
+	 * @param property the property to query.
+	 * @return the value of the given string property attached to the given device.
+	 * @see OpenVRInput#getTrackedControllerCount()
+	 * @see JOpenVRLibrary.ETrackedDeviceProperty
+	 * @see #getTrackedDeviceStringProperty(VR_IVRSystem_FnTable, int, int, int)
+	 */
+	public static String getTrackedDeviceStringProperty(VR_IVRSystem_FnTable system, int deviceIndex, int property){
+      return getTrackedDeviceStringProperty(system, deviceIndex, property, 256);
+	}
+	
+	/**
+	 * Get the String description of the given {@link ETrackedPropertyError string tracked property error}.
+	 * @param error the string tracked property error.
+	 * @return the String description of the given string tracked property error.
+	 */
+	public static String getETrackedPropertyErrorString(int error){
+		String str ="";
+		
+		switch(error){
+		case ETrackedPropertyError.ETrackedPropertyError_TrackedProp_Success:
+			str = "Success";
+			break;
+		case ETrackedPropertyError.ETrackedPropertyError_TrackedProp_WrongDataType:
+			str = "Wrong data type";
+			break;
+		case ETrackedPropertyError.ETrackedPropertyError_TrackedProp_WrongDeviceClass:
+			str = "Wrong device class";
+			break;
+		case ETrackedPropertyError.ETrackedPropertyError_TrackedProp_BufferTooSmall:
+			str = "Buffer too small";
+			break;
+		case ETrackedPropertyError.ETrackedPropertyError_TrackedProp_UnknownProperty:
+			str = "Unknown property";
+			break;
+		case ETrackedPropertyError.ETrackedPropertyError_TrackedProp_InvalidDevice:
+			str = "Invalid device";
+			break;
+		case ETrackedPropertyError.ETrackedPropertyError_TrackedProp_CouldNotContactServer:
+			str = "Could not contact server";
+			break;
+		case ETrackedPropertyError.ETrackedPropertyError_TrackedProp_ValueNotProvidedByDevice:
+			str = "Value not provided by device";
+			break;
+		case ETrackedPropertyError.ETrackedPropertyError_TrackedProp_StringExceedsMaximumLength:
+			str = "String exceed maximum length";
+			break;
+		case ETrackedPropertyError.ETrackedPropertyError_TrackedProp_NotYetAvailable:
+			str = "Not yet available";
+			break;
+		case ETrackedPropertyError.ETrackedPropertyError_TrackedProp_PermissionDenied:
+			str = "Permission denied";
+			break;
+		case ETrackedPropertyError.ETrackedPropertyError_TrackedProp_InvalidOperation:
+			str = "Invalid operation";
+			break;
+		default:
+			str = "Not handled error";
+		}
+		
+		return str;
+	}
+	
+	/**
+	 * Get the description of the given {@link EColorSpace color space}.
+	 * @param eColorSpace the color space.
+	 * @return the description of the given color space.
+	 */
+	public static String getEColorSpaceString(int eColorSpace){
+		String str = "";
+		
+		switch(eColorSpace){
+		  case EColorSpace.EColorSpace_ColorSpace_Auto:
+			  str = "Auto";
+			  break;
+		  case EColorSpace.EColorSpace_ColorSpace_Gamma:
+			  str = "Gamma";
+			  break;
+		  case EColorSpace.EColorSpace_ColorSpace_Linear:
+			  str = "Linear";
+			  break;
+		  default:
+			  str = "Unknown ("+eColorSpace+")";
+		}
+		
+		return str;
+	}
+	
+	/**
+	 * Get the description of the given {@link ETextureType texture type}.
+	 * @param type the texture type
+	 * @return the description of the given texture type.
+	 */
+	public static String getETextureTypeString(int type){
+		
+		String str = "";
+		
+		switch(type){
+		  case ETextureType.ETextureType_TextureType_DirectX:
+			  str = "DirectX";
+			  break;
+		  case ETextureType.ETextureType_TextureType_OpenGL:
+			  str = "OpenGL";
+			  break;
+		  case ETextureType.ETextureType_TextureType_Vulkan:
+			  str = "Vulkan";
+			  break;
+		  case ETextureType.ETextureType_TextureType_IOSurface:
+			  str = "IOSurface";
+			  break;
+		  case ETextureType.ETextureType_TextureType_DirectX12:
+			  str = "DirectX12";
+			  break;
+		  default: 
+			  str = "Unknown ("+type+")";
+		}
+		
+		return str;
+	}
+	
+	/**
+	 * Get the description of the given {@link EVRCompositorError EVR compositor error}.
+	 * @param error the EVR compositor error.
+	 * @return the description of the given EVR compositor error.
+	 */
+	public static String getEVRCompositorErrorString(int error){
+		String str ="";
+		
+		switch(error){
+		  case EVRCompositorError.EVRCompositorError_VRCompositorError_None: 
+			  str = "None"; 
+		  break;
+		  case EVRCompositorError.EVRCompositorError_VRCompositorError_RequestFailed: 
+			  str = "Request failed"; 
+		  break;
+		  case EVRCompositorError.EVRCompositorError_VRCompositorError_IncompatibleVersion: 
+			  str = "Incompatible version"; 
+		  break;
+		  case EVRCompositorError.EVRCompositorError_VRCompositorError_DoNotHaveFocus: 
+			  str = "Do not have focus"; 
+		  break;
+		  case EVRCompositorError.EVRCompositorError_VRCompositorError_InvalidTexture: 
+             str = "Invalid texture"; 
+		  break;
+		  case EVRCompositorError.EVRCompositorError_VRCompositorError_IsNotSceneApplication: 
+			  str = "Is not scene application"; 
+		  break;
+		  case EVRCompositorError.EVRCompositorError_VRCompositorError_TextureIsOnWrongDevice: 
+			  str = "Texture is on wrong device"; 
+		  break;
+		  case EVRCompositorError.EVRCompositorError_VRCompositorError_TextureUsesUnsupportedFormat: 
+			  str = "Texture uses unsupported format"; 
+		  break;
+		  case EVRCompositorError.EVRCompositorError_VRCompositorError_SharedTexturesNotSupported: 
+			  str = "Shared textures not supported"; 
+		  break;
+		  case EVRCompositorError.EVRCompositorError_VRCompositorError_IndexOutOfRange: 
+			  str = "Index out of range"; 
+		  break;
+		  case EVRCompositorError.EVRCompositorError_VRCompositorError_AlreadySubmitted: 
+			  str = "Already submitted"; 
+		  break;
+		}
+		return str;
+	}
+	
+	/**
+	 * Get the description of the given {@link EVRInitError EVR init error}.
+	 * @param error the EVR init error.
+	 * @return the description of the given EVR init error.
+	 */
+	public static String getEVRInitErrorString(int error){
+		String str = "";
+		
+		switch(error){
+		
+		
+		case EVRInitError.EVRInitError_VRInitError_None: 
+			str="None"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Unknown: 
+			str="Unknown"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_InstallationNotFound: 
+			str="Installation not found"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_InstallationCorrupt: 
+			str="Installation corrupt"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_VRClientDLLNotFound: 
+			str="VR Client DLL not found"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_FileNotFound: 
+			str="File not found"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_FactoryNotFound: 
+			str="Factory not found"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_InterfaceNotFound: 
+			str="Interface not found"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_InvalidInterface: 
+			str="Invalid interface"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_UserConfigDirectoryInvalid: 
+			str="User config directory invalid"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_HmdNotFound: 
+			str="HMD not found"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_NotInitialized: 
+			str="Not initialized"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_PathRegistryNotFound: 
+			str="Path registry not found"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_NoConfigPath: 
+			str="No config path"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_NoLogPath: 
+			str="No log path"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_PathRegistryNotWritable: 
+			str="Path registry not writable"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_AppInfoInitFailed: 
+			str="AppInfo init failed"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_Retry: 
+			str="Init retry";
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_InitCanceledByUser: 
+			str="Init canceled by user"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_AnotherAppLaunching: 
+			str="Another app launching"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_SettingsInitFailed: 
+			str="Setting init failed"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_ShuttingDown: 
+			str="Shutting down"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_TooManyObjects: 
+			str="Too many objects"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_NoServerForBackgroundApp: 
+			str="No server background app"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_NotSupportedWithCompositor: 
+			str="Not supported with compositor"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_NotAvailableToUtilityApps: 
+			str="Not available to utility apps"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_Internal: 
+			str="Internal"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_HmdDriverIdIsNone: 
+			str="Driver Id is None"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_HmdNotFoundPresenceFailed: 
+			str="HMD not found presence failed"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_VRMonitorNotFound: 
+			str="VR monitor not found"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_VRMonitorStartupFailed: 
+			str="VR monitor startup failed"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_LowPowerWatchdogNotSupported: 
+			str="Low power watchdog not supported"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_InvalidApplicationType: 
+			str="Invalid application type"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_NotAvailableToWatchdogApps: 
+			str="Not available to watchdog apps"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_WatchdogDisabledInSettings: 
+			str="Watchdog disabled in settings"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_VRDashboardNotFound: 
+			str="VR dashboard not found"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Init_VRDashboardStartupFailed: 
+			str="VR dashboard setup failed"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Driver_Failed: 
+			str="Driver failed"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Driver_Unknown: 
+			str="Driver unknown"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Driver_HmdUnknown: 
+			str="HMD unknown"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Driver_NotLoaded: 
+			str="Driver not loaded"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Driver_RuntimeOutOfDate: 
+			str="Driver runtime out of date"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Driver_HmdInUse: 
+			str="HMD in use"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Driver_NotCalibrated: 
+			str="Not calibrated"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Driver_CalibrationInvalid: 
+			str="Calibration invalid"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Driver_HmdDisplayNotFound: 
+			str="HMD display not found"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Driver_TrackedDeviceInterfaceUnknown: 
+			str="Tracked device interface unknown"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Driver_HmdDriverIdOutOfBounds: 
+			str="HMD driver Id out of bounds"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_Driver_HmdDisplayMirrored: 
+			str="HMD display mirrored"; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_IPC_ServerInitFailed: 
+			str=""; 
+			break;
+		case EVRInitError.EVRInitError_VRInitError_IPC_ConnectFailed: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_IPC_SharedStateInitFailed: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_IPC_CompositorInitFailed: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_IPC_MutexInitFailed: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_IPC_Failed: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_IPC_CompositorConnectFailed: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_IPC_CompositorInvalidConnectResponse: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_IPC_ConnectFailedAfterMultipleAttempts: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_Compositor_Failed: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_Compositor_D3D11HardwareRequired: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_Compositor_FirmwareRequiresUpdate: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_Compositor_OverlayInitFailed: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_Compositor_ScreenshotsInitFailed: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_VendorSpecific_UnableToConnectToOculusRuntime: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_VendorSpecific_HmdFound_CantOpenDevice: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_VendorSpecific_HmdFound_NoStoredConfig: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_VendorSpecific_HmdFound_ConfigTooBig: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_VendorSpecific_HmdFound_ConfigTooSmall: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_VendorSpecific_HmdFound_UnableToInitZLib: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_VendorSpecific_HmdFound_CantReadFirmwareVersion: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_VendorSpecific_HmdFound_UnableToSendUserDataStart: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataStart: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataNext: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_VendorSpecific_HmdFound_UserDataAddressRange: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_VendorSpecific_HmdFound_UserDataError: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_VendorSpecific_HmdFound_ConfigFailedSanityCheck: str=""; break;
+		case EVRInitError.EVRInitError_VRInitError_Steam_SteamInstallationNotFound: str=""; break;
+		default:
+	    }
+		
+		return str;
+	}
+	
+	/**
+	 * Get the description of the given tracked device property.
+	 * @param property the tracked device property.
+	 * @return the description of the given tracked device property.
+	 */
+	public static String getETrackedDevicePropertyString(int property){
+		String str = "";
+
+		switch(property){
+		
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_Invalid:
+			str = "Invalid";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_TrackingSystemName_String:
+			str = "Tracking system name";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_ModelNumber_String:
+			str = "Model number";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_SerialNumber_String:
+			str = "Serial number";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_RenderModelName_String:
+			str = "Render model name";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_WillDriftInYaw_Bool:
+			str = "Will drift in yaw";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_ManufacturerName_String:
+			str = "Manufacturer name";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_TrackingFirmwareVersion_String:
+			str = "Tracking firmware version";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_HardwareRevision_String:
+			str = "Hardware revision";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_AllWirelessDongleDescriptions_String:
+			str = "All wireless dongle descriptions";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_ConnectedWirelessDongle_String:
+			str = "Connect wireless dongle";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DeviceIsWireless_Bool:
+			str = "Device is wireless";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DeviceIsCharging_Bool:
+			str = "Device is charging";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DeviceBatteryPercentage_Float:
+			str = "Device battery percentage";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_StatusDisplayTransform_Matrix34:
+			str = "Status display transform";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_Firmware_UpdateAvailable_Bool:
+			str = "Update available";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_Firmware_ManualUpdate_Bool:
+			str = "Firmware manual update";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_Firmware_ManualUpdateURL_String:
+			str = "Firmware manual update URL";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_HardwareRevision_Uint64:
+			str = "Hardware revision";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_FirmwareVersion_Uint64:
+			str = "Firmware version";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_FPGAVersion_Uint64:
+			str = "FPGA version";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_VRCVersion_Uint64:
+			str = "VRC version";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_RadioVersion_Uint64:
+			str = "Radio version";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DongleVersion_Uint64:
+			str = "Dongle version";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_BlockServerShutdown_Bool:
+			str = "Block server shutdown";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_CanUnifyCoordinateSystemWithHmd_Bool:
+			str = "Can unify coordinate system with HMD";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_ContainsProximitySensor_Bool:
+			str = "Contains proximity sensor";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DeviceProvidesBatteryStatus_Bool:
+			str = "Device provides battery status";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DeviceCanPowerOff_Bool:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_Firmware_ProgrammingTarget_String:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DeviceClass_Int32:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_HasCamera_Bool:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DriverVersion_String:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_Firmware_ForceUpdateRequired_Bool:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_ViveSystemButtonFixRequired_Bool:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_ParentDriver_Uint64:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_ReportsTimeSinceVSync_Bool:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_SecondsFromVsyncToPhotons_Float:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayFrequency_Float:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_UserIpdMeters_Float:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_CurrentUniverseId_Uint64:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_PreviousUniverseId_Uint64:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayFirmwareVersion_Uint64:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_IsOnDesktop_Bool:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayMCType_Int32:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayMCOffset_Float:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayMCScale_Float:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_EdidVendorID_Int32:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayMCImageLeft_String:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayMCImageRight_String:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayGCBlackClamp_Float:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_EdidProductID_Int32:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_CameraToHeadTransform_Matrix34:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayGCType_Int32:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayGCOffset_Float:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayGCScale_Float:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayGCPrescale_Float:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayGCImage_String:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_LensCenterLeftU_Float:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_LensCenterLeftV_Float:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_LensCenterRightU_Float:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_LensCenterRightV_Float:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_UserHeadToEyeDepthMeters_Float:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_CameraFirmwareVersion_Uint64:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_CameraFirmwareDescription_String:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayFPGAVersion_Uint64:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayBootloaderVersion_Uint64:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayHardwareVersion_Uint64:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_AudioFirmwareVersion_Uint64:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_CameraCompatibilityMode_Int32:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_ScreenshotHorizontalFieldOfViewDegrees_Float:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_ScreenshotVerticalFieldOfViewDegrees_Float:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplaySuppressed_Bool:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayAllowNightMode_Bool:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayMCImageWidth_Int32:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayMCImageHeight_Int32:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayMCImageNumChannels_Int32:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayMCImageData_Binary:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_UsesDriverDirectMode_Bool:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_AttachedDeviceId_String:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_SupportedButtons_Uint64:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_Axis0Type_Int32:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_Axis1Type_Int32:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_Axis2Type_Int32:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_Axis3Type_Int32:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_Axis4Type_Int32:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_ControllerRoleHint_Int32:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_FieldOfViewLeftDegrees_Float:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_FieldOfViewRightDegrees_Float:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_FieldOfViewTopDegrees_Float:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_FieldOfViewBottomDegrees_Float:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_TrackingRangeMinimumMeters_Float:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_TrackingRangeMaximumMeters_Float:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_ModeLabel_String:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_IconPathName_String:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_NamedIconPathDeviceOff_String:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_NamedIconPathDeviceSearching_String:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_NamedIconPathDeviceSearchingAlert_String:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_NamedIconPathDeviceReady_String:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_NamedIconPathDeviceReadyAlert_String:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_NamedIconPathDeviceNotReady_String:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_NamedIconPathDeviceStandby_String:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_NamedIconPathDeviceAlertLow_String:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayHiddenArea_Binary_Start:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_DisplayHiddenArea_Binary_End:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_UserConfigPath_String:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_InstallPath_String:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_VendorSpecific_Reserved_Start:
+			str = "";
+			break;
+		case ETrackedDeviceProperty.ETrackedDeviceProperty_Prop_VendorSpecific_Reserved_End:
+			str = "";
+			break;
+		}
+		
+		
+		return str;
+	}
+}

+ 45 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/RenderModel_ComponentState_t.java

@@ -0,0 +1,45 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1205</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class RenderModel_ComponentState_t extends Structure {
+	/** C type : HmdMatrix34_t */
+	public HmdMatrix34_t mTrackingToComponentRenderModel;
+	/** C type : HmdMatrix34_t */
+	public HmdMatrix34_t mTrackingToComponentLocal;
+	/** C type : VRComponentProperties */
+	public int uProperties;
+	public RenderModel_ComponentState_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("mTrackingToComponentRenderModel", "mTrackingToComponentLocal", "uProperties");
+	}
+	/**
+	 * @param mTrackingToComponentRenderModel C type : HmdMatrix34_t<br>
+	 * @param mTrackingToComponentLocal C type : HmdMatrix34_t<br>
+	 * @param uProperties C type : VRComponentProperties
+	 */
+	public RenderModel_ComponentState_t(HmdMatrix34_t mTrackingToComponentRenderModel, HmdMatrix34_t mTrackingToComponentLocal, int uProperties) {
+		super();
+		this.mTrackingToComponentRenderModel = mTrackingToComponentRenderModel;
+		this.mTrackingToComponentLocal = mTrackingToComponentLocal;
+		this.uProperties = uProperties;
+	}
+	public RenderModel_ComponentState_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends RenderModel_ComponentState_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends RenderModel_ComponentState_t implements Structure.ByValue {
+		
+	};
+}

+ 33 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/RenderModel_ControllerMode_State_t.java

@@ -0,0 +1,33 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1229</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class RenderModel_ControllerMode_State_t extends Structure {
+	public byte bScrollWheelVisible;
+	public RenderModel_ControllerMode_State_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("bScrollWheelVisible");
+	}
+	public RenderModel_ControllerMode_State_t(byte bScrollWheelVisible) {
+		super();
+		this.bScrollWheelVisible = bScrollWheelVisible;
+	}
+	public RenderModel_ControllerMode_State_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends RenderModel_ControllerMode_State_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends RenderModel_ControllerMode_State_t implements Structure.ByValue {
+		
+	};
+}

+ 45 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/RenderModel_TextureMap_t.java

@@ -0,0 +1,45 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1217</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class RenderModel_TextureMap_t extends Structure {
+	public short unWidth;
+	public short unHeight;
+	/**
+	 * const uint8_t *<br>
+	 * C type : uint8_t*
+	 */
+	public Pointer rubTextureMapData;
+	public RenderModel_TextureMap_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("unWidth", "unHeight", "rubTextureMapData");
+	}
+	/**
+	 * @param rubTextureMapData const uint8_t *<br>
+	 * C type : uint8_t*
+	 */
+	public RenderModel_TextureMap_t(short unWidth, short unHeight, Pointer rubTextureMapData) {
+		super();
+		this.unWidth = unWidth;
+		this.unHeight = unHeight;
+		this.rubTextureMapData = rubTextureMapData;
+	}
+	public RenderModel_TextureMap_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends RenderModel_TextureMap_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends RenderModel_TextureMap_t implements Structure.ByValue {
+		
+	};
+}

+ 51 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/RenderModel_Vertex_t.java

@@ -0,0 +1,51 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1211</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class RenderModel_Vertex_t extends Structure {
+	/** C type : HmdVector3_t */
+	public HmdVector3_t vPosition;
+	/** C type : HmdVector3_t */
+	public HmdVector3_t vNormal;
+	/**
+	 * float[2]<br>
+	 * C type : float[2]
+	 */
+	public float[] rfTextureCoord = new float[2];
+	public RenderModel_Vertex_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("vPosition", "vNormal", "rfTextureCoord");
+	}
+	/**
+	 * @param vPosition C type : HmdVector3_t<br>
+	 * @param vNormal C type : HmdVector3_t<br>
+	 * @param rfTextureCoord float[2]<br>
+	 * C type : float[2]
+	 */
+	public RenderModel_Vertex_t(HmdVector3_t vPosition, HmdVector3_t vNormal, float rfTextureCoord[]) {
+		super();
+		this.vPosition = vPosition;
+		this.vNormal = vNormal;
+		if ((rfTextureCoord.length != this.rfTextureCoord.length)) 
+			throw new IllegalArgumentException("Wrong array size !");
+		this.rfTextureCoord = rfTextureCoord;
+	}
+	public RenderModel_Vertex_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends RenderModel_Vertex_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends RenderModel_Vertex_t implements Structure.ByValue {
+		
+	};
+}

+ 58 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/RenderModel_t.java

@@ -0,0 +1,58 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import com.sun.jna.ptr.ShortByReference;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1226</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class RenderModel_t extends Structure {
+	/**
+	 * const struct vr::RenderModel_Vertex_t *<br>
+	 * C type : RenderModel_Vertex_t*
+	 */
+	public com.jme3.system.jopenvr.RenderModel_Vertex_t.ByReference rVertexData;
+	public int unVertexCount;
+	/**
+	 * const uint16_t *<br>
+	 * C type : uint16_t*
+	 */
+	public ShortByReference rIndexData;
+	public int unTriangleCount;
+	/** C type : TextureID_t */
+	public int diffuseTextureId;
+	public RenderModel_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("rVertexData", "unVertexCount", "rIndexData", "unTriangleCount", "diffuseTextureId");
+	}
+	/**
+	 * @param rVertexData const struct vr::RenderModel_Vertex_t *<br>
+	 * C type : RenderModel_Vertex_t*<br>
+	 * @param rIndexData const uint16_t *<br>
+	 * C type : uint16_t*<br>
+	 * @param diffuseTextureId C type : TextureID_t
+	 */
+	public RenderModel_t(com.jme3.system.jopenvr.RenderModel_Vertex_t.ByReference rVertexData, int unVertexCount, ShortByReference rIndexData, int unTriangleCount, int diffuseTextureId) {
+		super();
+		this.rVertexData = rVertexData;
+		this.unVertexCount = unVertexCount;
+		this.rIndexData = rIndexData;
+		this.unTriangleCount = unTriangleCount;
+		this.diffuseTextureId = diffuseTextureId;
+	}
+	public RenderModel_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends RenderModel_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends RenderModel_t implements Structure.ByValue {
+		
+	};
+}

+ 57 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/Texture_t.java

@@ -0,0 +1,57 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:964</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class Texture_t extends Structure {
+	/**
+	 * void *<br>
+	 * C type : void*
+	 */
+	public int handle;
+	/**
+	 * @see ETextureType<br>
+	 * C type : ETextureType
+	 */
+	public int eType;
+	/**
+	 * @see EColorSpace<br>
+	 * C type : EColorSpace
+	 */
+	public int eColorSpace;
+	public Texture_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("handle", "eType", "eColorSpace");
+	}
+	/**
+	 * @param handle void *<br>
+	 * C type : void*<br>
+	 * @param eType @see ETextureType<br>
+	 * C type : ETextureType<br>
+	 * @param eColorSpace @see EColorSpace<br>
+	 * C type : EColorSpace
+	 */
+	public Texture_t(int handle, int eType, int eColorSpace) {
+		super();
+		this.handle = handle;
+		this.eType = eType;
+		this.eColorSpace = eColorSpace;
+	}
+	public Texture_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends Texture_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends Texture_t implements Structure.ByValue {
+		
+	};
+}

+ 57 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/TrackedDevicePose_t.java

@@ -0,0 +1,57 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:974</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class TrackedDevicePose_t extends Structure {
+	/** C type : HmdMatrix34_t */
+	public HmdMatrix34_t mDeviceToAbsoluteTracking;
+	/** C type : HmdVector3_t */
+	public HmdVector3_t vVelocity;
+	/** C type : HmdVector3_t */
+	public HmdVector3_t vAngularVelocity;
+	/**
+	 * @see ETrackingResult<br>
+	 * C type : ETrackingResult
+	 */
+	public int eTrackingResult;
+	public byte bPoseIsValid;
+	public byte bDeviceIsConnected;
+	public TrackedDevicePose_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("mDeviceToAbsoluteTracking", "vVelocity", "vAngularVelocity", "eTrackingResult", "bPoseIsValid", "bDeviceIsConnected");
+	}
+	/**
+	 * @param mDeviceToAbsoluteTracking C type : HmdMatrix34_t<br>
+	 * @param vVelocity C type : HmdVector3_t<br>
+	 * @param vAngularVelocity C type : HmdVector3_t<br>
+	 * @param eTrackingResult @see ETrackingResult<br>
+	 * C type : ETrackingResult
+	 */
+	public TrackedDevicePose_t(HmdMatrix34_t mDeviceToAbsoluteTracking, HmdVector3_t vVelocity, HmdVector3_t vAngularVelocity, int eTrackingResult, byte bPoseIsValid, byte bDeviceIsConnected) {
+		super();
+		this.mDeviceToAbsoluteTracking = mDeviceToAbsoluteTracking;
+		this.vVelocity = vVelocity;
+		this.vAngularVelocity = vAngularVelocity;
+		this.eTrackingResult = eTrackingResult;
+		this.bPoseIsValid = bPoseIsValid;
+		this.bDeviceIsConnected = bDeviceIsConnected;
+	}
+	public TrackedDevicePose_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends TrackedDevicePose_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends TrackedDevicePose_t implements Structure.ByValue {
+		
+	};
+}

+ 35 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VRControllerAxis_t.java

@@ -0,0 +1,35 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1094</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VRControllerAxis_t extends Structure {
+	public float x;
+	public float y;
+	public VRControllerAxis_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("x", "y");
+	}
+	public VRControllerAxis_t(float x, float y) {
+		super();
+		this.x = x;
+		this.y = y;
+	}
+	public VRControllerAxis_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VRControllerAxis_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VRControllerAxis_t implements Structure.ByValue {
+		
+	};
+}

+ 49 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VRControllerState_t.java

@@ -0,0 +1,49 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1101</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VRControllerState_t extends Structure {
+	public int unPacketNum;
+	public long ulButtonPressed;
+	public long ulButtonTouched;
+	/**
+	 * struct vr::VRControllerAxis_t[5]<br>
+	 * C type : VRControllerAxis_t[5]
+	 */
+	public VRControllerAxis_t[] rAxis = new VRControllerAxis_t[5];
+	public VRControllerState_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("unPacketNum", "ulButtonPressed", "ulButtonTouched", "rAxis");
+	}
+	/**
+	 * @param rAxis struct vr::VRControllerAxis_t[5]<br>
+	 * C type : VRControllerAxis_t[5]
+	 */
+	public VRControllerState_t(int unPacketNum, long ulButtonPressed, long ulButtonTouched, VRControllerAxis_t rAxis[]) {
+		super();
+		this.unPacketNum = unPacketNum;
+		this.ulButtonPressed = ulButtonPressed;
+		this.ulButtonTouched = ulButtonTouched;
+		if ((rAxis.length != this.rAxis.length)) 
+			throw new IllegalArgumentException("Wrong array size !");
+		this.rAxis = rAxis;
+	}
+	public VRControllerState_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VRControllerState_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VRControllerState_t implements Structure.ByValue {
+		
+	};
+}

+ 35 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_ApplicationLaunch_t.java

@@ -0,0 +1,35 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1072</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VREvent_ApplicationLaunch_t extends Structure {
+	public int pid;
+	public int unArgsHandle;
+	public VREvent_ApplicationLaunch_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("pid", "unArgsHandle");
+	}
+	public VREvent_ApplicationLaunch_t(int pid, int unArgsHandle) {
+		super();
+		this.pid = pid;
+		this.unArgsHandle = unArgsHandle;
+	}
+	public VREvent_ApplicationLaunch_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VREvent_ApplicationLaunch_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VREvent_ApplicationLaunch_t implements Structure.ByValue {
+		
+	};
+}

+ 35 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Chaperone_t.java

@@ -0,0 +1,35 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1051</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VREvent_Chaperone_t extends Structure {
+	public long m_nPreviousUniverse;
+	public long m_nCurrentUniverse;
+	public VREvent_Chaperone_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("m_nPreviousUniverse", "m_nCurrentUniverse");
+	}
+	public VREvent_Chaperone_t(long m_nPreviousUniverse, long m_nCurrentUniverse) {
+		super();
+		this.m_nPreviousUniverse = m_nPreviousUniverse;
+		this.m_nCurrentUniverse = m_nCurrentUniverse;
+	}
+	public VREvent_Chaperone_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VREvent_Chaperone_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VREvent_Chaperone_t implements Structure.ByValue {
+		
+	};
+}

+ 33 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Controller_t.java

@@ -0,0 +1,33 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1006</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VREvent_Controller_t extends Structure {
+	public int button;
+	public VREvent_Controller_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("button");
+	}
+	public VREvent_Controller_t(int button) {
+		super();
+		this.button = button;
+	}
+	public VREvent_Controller_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VREvent_Controller_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VREvent_Controller_t implements Structure.ByValue {
+		
+	};
+}

+ 135 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Data_t.java

@@ -0,0 +1,135 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Union;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1278</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VREvent_Data_t extends Union {
+	/** C type : VREvent_Reserved_t */
+	public VREvent_Reserved_t reserved;
+	/** C type : VREvent_Controller_t */
+	public VREvent_Controller_t controller;
+	/** C type : VREvent_Mouse_t */
+	public VREvent_Mouse_t mouse;
+	/** C type : VREvent_Scroll_t */
+	public VREvent_Scroll_t scroll;
+	/** C type : VREvent_Process_t */
+	public VREvent_Process_t process;
+	/** C type : VREvent_Notification_t */
+	public VREvent_Notification_t notification;
+	/** C type : VREvent_Overlay_t */
+	public VREvent_Overlay_t overlay;
+	/** C type : VREvent_Status_t */
+	public VREvent_Status_t status;
+	/** C type : VREvent_Keyboard_t */
+	public VREvent_Keyboard_t keyboard;
+	/** C type : VREvent_Ipd_t */
+	public VREvent_Ipd_t ipd;
+	/** C type : VREvent_Chaperone_t */
+	public VREvent_Chaperone_t chaperone;
+	/** C type : VREvent_PerformanceTest_t */
+	public VREvent_PerformanceTest_t performanceTest;
+	/** C type : VREvent_TouchPadMove_t */
+	public VREvent_TouchPadMove_t touchPadMove;
+	/** C type : VREvent_SeatedZeroPoseReset_t */
+	public VREvent_SeatedZeroPoseReset_t seatedZeroPoseReset;
+	public VREvent_Data_t() {
+		super();
+	}
+	/** @param reserved C type : VREvent_Reserved_t */
+	public VREvent_Data_t(VREvent_Reserved_t reserved) {
+		super();
+		this.reserved = reserved;
+		setType(VREvent_Reserved_t.class);
+	}
+	/** @param controller C type : VREvent_Controller_t */
+	public VREvent_Data_t(VREvent_Controller_t controller) {
+		super();
+		this.controller = controller;
+		setType(VREvent_Controller_t.class);
+	}
+	/** @param mouse C type : VREvent_Mouse_t */
+	public VREvent_Data_t(VREvent_Mouse_t mouse) {
+		super();
+		this.mouse = mouse;
+		setType(VREvent_Mouse_t.class);
+	}
+	/** @param scroll C type : VREvent_Scroll_t */
+	public VREvent_Data_t(VREvent_Scroll_t scroll) {
+		super();
+		this.scroll = scroll;
+		setType(VREvent_Scroll_t.class);
+	}
+	/** @param process C type : VREvent_Process_t */
+	public VREvent_Data_t(VREvent_Process_t process) {
+		super();
+		this.process = process;
+		setType(VREvent_Process_t.class);
+	}
+	/** @param notification C type : VREvent_Notification_t */
+	public VREvent_Data_t(VREvent_Notification_t notification) {
+		super();
+		this.notification = notification;
+		setType(VREvent_Notification_t.class);
+	}
+	/** @param overlay C type : VREvent_Overlay_t */
+	public VREvent_Data_t(VREvent_Overlay_t overlay) {
+		super();
+		this.overlay = overlay;
+		setType(VREvent_Overlay_t.class);
+	}
+	/** @param status C type : VREvent_Status_t */
+	public VREvent_Data_t(VREvent_Status_t status) {
+		super();
+		this.status = status;
+		setType(VREvent_Status_t.class);
+	}
+	/** @param keyboard C type : VREvent_Keyboard_t */
+	public VREvent_Data_t(VREvent_Keyboard_t keyboard) {
+		super();
+		this.keyboard = keyboard;
+		setType(VREvent_Keyboard_t.class);
+	}
+	/** @param ipd C type : VREvent_Ipd_t */
+	public VREvent_Data_t(VREvent_Ipd_t ipd) {
+		super();
+		this.ipd = ipd;
+		setType(VREvent_Ipd_t.class);
+	}
+	/** @param chaperone C type : VREvent_Chaperone_t */
+	public VREvent_Data_t(VREvent_Chaperone_t chaperone) {
+		super();
+		this.chaperone = chaperone;
+		setType(VREvent_Chaperone_t.class);
+	}
+	/** @param performanceTest C type : VREvent_PerformanceTest_t */
+	public VREvent_Data_t(VREvent_PerformanceTest_t performanceTest) {
+		super();
+		this.performanceTest = performanceTest;
+		setType(VREvent_PerformanceTest_t.class);
+	}
+	/** @param touchPadMove C type : VREvent_TouchPadMove_t */
+	public VREvent_Data_t(VREvent_TouchPadMove_t touchPadMove) {
+		super();
+		this.touchPadMove = touchPadMove;
+		setType(VREvent_TouchPadMove_t.class);
+	}
+	/** @param seatedZeroPoseReset C type : VREvent_SeatedZeroPoseReset_t */
+	public VREvent_Data_t(VREvent_SeatedZeroPoseReset_t seatedZeroPoseReset) {
+		super();
+		this.seatedZeroPoseReset = seatedZeroPoseReset;
+		setType(VREvent_SeatedZeroPoseReset_t.class);
+	}
+	public VREvent_Data_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VREvent_Data_t implements com.sun.jna.Structure.ByReference {
+		
+	};
+	public static class ByValue extends VREvent_Data_t implements com.sun.jna.Structure.ByValue {
+		
+	};
+}

+ 35 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_EditingCameraSurface_t.java

@@ -0,0 +1,35 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1076</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VREvent_EditingCameraSurface_t extends Structure {
+	public long overlayHandle;
+	public int nVisualMode;
+	public VREvent_EditingCameraSurface_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("overlayHandle", "nVisualMode");
+	}
+	public VREvent_EditingCameraSurface_t(long overlayHandle, int nVisualMode) {
+		super();
+		this.overlayHandle = overlayHandle;
+		this.nVisualMode = nVisualMode;
+	}
+	public VREvent_EditingCameraSurface_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VREvent_EditingCameraSurface_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VREvent_EditingCameraSurface_t implements Structure.ByValue {
+		
+	};
+}

+ 33 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Ipd_t.java

@@ -0,0 +1,33 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1047</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VREvent_Ipd_t extends Structure {
+	public float ipdMeters;
+	public VREvent_Ipd_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("ipdMeters");
+	}
+	public VREvent_Ipd_t(float ipdMeters) {
+		super();
+		this.ipdMeters = ipdMeters;
+	}
+	public VREvent_Ipd_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VREvent_Ipd_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VREvent_Ipd_t implements Structure.ByValue {
+		
+	};
+}

+ 45 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Keyboard_t.java

@@ -0,0 +1,45 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1044</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VREvent_Keyboard_t extends Structure {
+	/**
+	 * char[8]<br>
+	 * C type : char*[8]
+	 */
+	public Pointer[] cNewInput = new Pointer[8];
+	public long uUserValue;
+	public VREvent_Keyboard_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("cNewInput", "uUserValue");
+	}
+	/**
+	 * @param cNewInput char[8]<br>
+	 * C type : char*[8]
+	 */
+	public VREvent_Keyboard_t(Pointer cNewInput[], long uUserValue) {
+		super();
+		if ((cNewInput.length != this.cNewInput.length)) 
+			throw new IllegalArgumentException("Wrong array size !");
+		this.cNewInput = cNewInput;
+		this.uUserValue = uUserValue;
+	}
+	public VREvent_Keyboard_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VREvent_Keyboard_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VREvent_Keyboard_t implements Structure.ByValue {
+		
+	};
+}

+ 33 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_MessageOverlay_t.java

@@ -0,0 +1,33 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1079</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VREvent_MessageOverlay_t extends Structure {
+	public int unVRMessageOverlayResponse;
+	public VREvent_MessageOverlay_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("unVRMessageOverlayResponse");
+	}
+	public VREvent_MessageOverlay_t(int unVRMessageOverlayResponse) {
+		super();
+		this.unVRMessageOverlayResponse = unVRMessageOverlayResponse;
+	}
+	public VREvent_MessageOverlay_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VREvent_MessageOverlay_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VREvent_MessageOverlay_t implements Structure.ByValue {
+		
+	};
+}

+ 37 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Mouse_t.java

@@ -0,0 +1,37 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1011</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VREvent_Mouse_t extends Structure {
+	public float x;
+	public float y;
+	public int button;
+	public VREvent_Mouse_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("x", "y", "button");
+	}
+	public VREvent_Mouse_t(float x, float y, int button) {
+		super();
+		this.x = x;
+		this.y = y;
+		this.button = button;
+	}
+	public VREvent_Mouse_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VREvent_Mouse_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VREvent_Mouse_t implements Structure.ByValue {
+		
+	};
+}

+ 35 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Notification_t.java

@@ -0,0 +1,35 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1028</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VREvent_Notification_t extends Structure {
+	public long ulUserValue;
+	public int notificationId;
+	public VREvent_Notification_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("ulUserValue", "notificationId");
+	}
+	public VREvent_Notification_t(long ulUserValue, int notificationId) {
+		super();
+		this.ulUserValue = ulUserValue;
+		this.notificationId = notificationId;
+	}
+	public VREvent_Notification_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VREvent_Notification_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VREvent_Notification_t implements Structure.ByValue {
+		
+	};
+}

+ 33 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Overlay_t.java

@@ -0,0 +1,33 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1036</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VREvent_Overlay_t extends Structure {
+	public long overlayHandle;
+	public VREvent_Overlay_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("overlayHandle");
+	}
+	public VREvent_Overlay_t(long overlayHandle) {
+		super();
+		this.overlayHandle = overlayHandle;
+	}
+	public VREvent_Overlay_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VREvent_Overlay_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VREvent_Overlay_t implements Structure.ByValue {
+		
+	};
+}

+ 33 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_PerformanceTest_t.java

@@ -0,0 +1,33 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1058</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VREvent_PerformanceTest_t extends Structure {
+	public int m_nFidelityLevel;
+	public VREvent_PerformanceTest_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("m_nFidelityLevel");
+	}
+	public VREvent_PerformanceTest_t(int m_nFidelityLevel) {
+		super();
+		this.m_nFidelityLevel = m_nFidelityLevel;
+	}
+	public VREvent_PerformanceTest_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VREvent_PerformanceTest_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VREvent_PerformanceTest_t implements Structure.ByValue {
+		
+	};
+}

+ 37 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Process_t.java

@@ -0,0 +1,37 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1033</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VREvent_Process_t extends Structure {
+	public int pid;
+	public int oldPid;
+	public byte bForced;
+	public VREvent_Process_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("pid", "oldPid", "bForced");
+	}
+	public VREvent_Process_t(int pid, int oldPid, byte bForced) {
+		super();
+		this.pid = pid;
+		this.oldPid = oldPid;
+		this.bForced = bForced;
+	}
+	public VREvent_Process_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VREvent_Process_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VREvent_Process_t implements Structure.ByValue {
+		
+	};
+}

+ 45 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Property_t.java

@@ -0,0 +1,45 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1085</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VREvent_Property_t extends Structure {
+	/** C type : PropertyContainerHandle_t */
+	public long container;
+	/**
+	 * @see ETrackedDeviceProperty<br>
+	 * C type : ETrackedDeviceProperty
+	 */
+	public int prop;
+	public VREvent_Property_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("container", "prop");
+	}
+	/**
+	 * @param container C type : PropertyContainerHandle_t<br>
+	 * @param prop @see ETrackedDeviceProperty<br>
+	 * C type : ETrackedDeviceProperty
+	 */
+	public VREvent_Property_t(long container, int prop) {
+		super();
+		this.container = container;
+		this.prop = prop;
+	}
+	public VREvent_Property_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VREvent_Property_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VREvent_Property_t implements Structure.ByValue {
+		
+	};
+}

+ 35 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Reserved_t.java

@@ -0,0 +1,35 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1055</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VREvent_Reserved_t extends Structure {
+	public long reserved0;
+	public long reserved1;
+	public VREvent_Reserved_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("reserved0", "reserved1");
+	}
+	public VREvent_Reserved_t(long reserved0, long reserved1) {
+		super();
+		this.reserved0 = reserved0;
+		this.reserved1 = reserved1;
+	}
+	public VREvent_Reserved_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VREvent_Reserved_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VREvent_Reserved_t implements Structure.ByValue {
+		
+	};
+}

+ 33 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_ScreenshotProgress_t.java

@@ -0,0 +1,33 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1068</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VREvent_ScreenshotProgress_t extends Structure {
+	public float progress;
+	public VREvent_ScreenshotProgress_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("progress");
+	}
+	public VREvent_ScreenshotProgress_t(float progress) {
+		super();
+		this.progress = progress;
+	}
+	public VREvent_ScreenshotProgress_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VREvent_ScreenshotProgress_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VREvent_ScreenshotProgress_t implements Structure.ByValue {
+		
+	};
+}

+ 35 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Screenshot_t.java

@@ -0,0 +1,35 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1065</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VREvent_Screenshot_t extends Structure {
+	public int handle;
+	public int type;
+	public VREvent_Screenshot_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("handle", "type");
+	}
+	public VREvent_Screenshot_t(int handle, int type) {
+		super();
+		this.handle = handle;
+		this.type = type;
+	}
+	public VREvent_Screenshot_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VREvent_Screenshot_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VREvent_Screenshot_t implements Structure.ByValue {
+		
+	};
+}

+ 37 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Scroll_t.java

@@ -0,0 +1,37 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1016</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VREvent_Scroll_t extends Structure {
+	public float xdelta;
+	public float ydelta;
+	public int repeatCount;
+	public VREvent_Scroll_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("xdelta", "ydelta", "repeatCount");
+	}
+	public VREvent_Scroll_t(float xdelta, float ydelta, int repeatCount) {
+		super();
+		this.xdelta = xdelta;
+		this.ydelta = ydelta;
+		this.repeatCount = repeatCount;
+	}
+	public VREvent_Scroll_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VREvent_Scroll_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VREvent_Scroll_t implements Structure.ByValue {
+		
+	};
+}

+ 33 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_SeatedZeroPoseReset_t.java

@@ -0,0 +1,33 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1061</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VREvent_SeatedZeroPoseReset_t extends Structure {
+	public byte bResetBySystemMenu;
+	public VREvent_SeatedZeroPoseReset_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("bResetBySystemMenu");
+	}
+	public VREvent_SeatedZeroPoseReset_t(byte bResetBySystemMenu) {
+		super();
+		this.bResetBySystemMenu = bResetBySystemMenu;
+	}
+	public VREvent_SeatedZeroPoseReset_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VREvent_SeatedZeroPoseReset_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VREvent_SeatedZeroPoseReset_t implements Structure.ByValue {
+		
+	};
+}

+ 33 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_Status_t.java

@@ -0,0 +1,33 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1039</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VREvent_Status_t extends Structure {
+	public int statusState;
+	public VREvent_Status_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("statusState");
+	}
+	public VREvent_Status_t(int statusState) {
+		super();
+		this.statusState = statusState;
+	}
+	public VREvent_Status_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VREvent_Status_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VREvent_Status_t implements Structure.ByValue {
+		
+	};
+}

+ 43 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_TouchPadMove_t.java

@@ -0,0 +1,43 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1024</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VREvent_TouchPadMove_t extends Structure {
+	public byte bFingerDown;
+	public float flSecondsFingerDown;
+	public float fValueXFirst;
+	public float fValueYFirst;
+	public float fValueXRaw;
+	public float fValueYRaw;
+	public VREvent_TouchPadMove_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("bFingerDown", "flSecondsFingerDown", "fValueXFirst", "fValueYFirst", "fValueXRaw", "fValueYRaw");
+	}
+	public VREvent_TouchPadMove_t(byte bFingerDown, float flSecondsFingerDown, float fValueXFirst, float fValueYFirst, float fValueXRaw, float fValueYRaw) {
+		super();
+		this.bFingerDown = bFingerDown;
+		this.flSecondsFingerDown = flSecondsFingerDown;
+		this.fValueXFirst = fValueXFirst;
+		this.fValueYFirst = fValueYFirst;
+		this.fValueXRaw = fValueXRaw;
+		this.fValueYRaw = fValueYRaw;
+	}
+	public VREvent_TouchPadMove_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VREvent_TouchPadMove_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VREvent_TouchPadMove_t implements Structure.ByValue {
+		
+	};
+}

+ 48 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VREvent_t.java

@@ -0,0 +1,48 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * An event posted by the server to all running applications<br>
+ * <i>native declaration : headers\openvr_capi.h:1286</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VREvent_t extends Structure {
+	/** EVREventType enum */
+	public int eventType;
+	/** C type : TrackedDeviceIndex_t */
+	public int trackedDeviceIndex;
+	public float eventAgeSeconds;
+	/** C type : VREvent_Data_t */
+	public VREvent_Data_t data;
+	public VREvent_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("eventType", "trackedDeviceIndex", "eventAgeSeconds", "data");
+	}
+	/**
+	 * @param eventType EVREventType enum<br>
+	 * @param trackedDeviceIndex C type : TrackedDeviceIndex_t<br>
+	 * @param data C type : VREvent_Data_t
+	 */
+	public VREvent_t(int eventType, int trackedDeviceIndex, float eventAgeSeconds, VREvent_Data_t data) {
+		super();
+		this.eventType = eventType;
+		this.trackedDeviceIndex = trackedDeviceIndex;
+		this.eventAgeSeconds = eventAgeSeconds;
+		this.data = data;
+	}
+	public VREvent_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VREvent_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VREvent_t implements Structure.ByValue {
+		
+	};
+}

+ 39 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VROverlayIntersectionMaskPrimitive_Data_t.java

@@ -0,0 +1,39 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Union;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1290</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VROverlayIntersectionMaskPrimitive_Data_t extends Union {
+	/** C type : IntersectionMaskRectangle_t */
+	public IntersectionMaskRectangle_t m_Rectangle;
+	/** C type : IntersectionMaskCircle_t */
+	public IntersectionMaskCircle_t m_Circle;
+	public VROverlayIntersectionMaskPrimitive_Data_t() {
+		super();
+	}
+	/** @param m_Rectangle C type : IntersectionMaskRectangle_t */
+	public VROverlayIntersectionMaskPrimitive_Data_t(IntersectionMaskRectangle_t m_Rectangle) {
+		super();
+		this.m_Rectangle = m_Rectangle;
+		setType(IntersectionMaskRectangle_t.class);
+	}
+	/** @param m_Circle C type : IntersectionMaskCircle_t */
+	public VROverlayIntersectionMaskPrimitive_Data_t(IntersectionMaskCircle_t m_Circle) {
+		super();
+		this.m_Circle = m_Circle;
+		setType(IntersectionMaskCircle_t.class);
+	}
+	public VROverlayIntersectionMaskPrimitive_Data_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VROverlayIntersectionMaskPrimitive_Data_t implements com.sun.jna.Structure.ByReference {
+		
+	};
+	public static class ByValue extends VROverlayIntersectionMaskPrimitive_Data_t implements com.sun.jna.Structure.ByValue {
+		
+	};
+}

+ 45 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VROverlayIntersectionMaskPrimitive_t.java

@@ -0,0 +1,45 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1294</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VROverlayIntersectionMaskPrimitive_t extends Structure {
+	/**
+	 * @see EVROverlayIntersectionMaskPrimitiveType<br>
+	 * C type : EVROverlayIntersectionMaskPrimitiveType
+	 */
+	public int m_nPrimitiveType;
+	/** C type : VROverlayIntersectionMaskPrimitive_Data_t */
+	public VROverlayIntersectionMaskPrimitive_Data_t m_Primitive;
+	public VROverlayIntersectionMaskPrimitive_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("m_nPrimitiveType", "m_Primitive");
+	}
+	/**
+	 * @param m_nPrimitiveType @see EVROverlayIntersectionMaskPrimitiveType<br>
+	 * C type : EVROverlayIntersectionMaskPrimitiveType<br>
+	 * @param m_Primitive C type : VROverlayIntersectionMaskPrimitive_Data_t
+	 */
+	public VROverlayIntersectionMaskPrimitive_t(int m_nPrimitiveType, VROverlayIntersectionMaskPrimitive_Data_t m_Primitive) {
+		super();
+		this.m_nPrimitiveType = m_nPrimitiveType;
+		this.m_Primitive = m_Primitive;
+	}
+	public VROverlayIntersectionMaskPrimitive_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VROverlayIntersectionMaskPrimitive_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VROverlayIntersectionMaskPrimitive_t implements Structure.ByValue {
+		
+	};
+}

+ 49 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VROverlayIntersectionParams_t.java

@@ -0,0 +1,49 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1183</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VROverlayIntersectionParams_t extends Structure {
+	/** C type : HmdVector3_t */
+	public HmdVector3_t vSource;
+	/** C type : HmdVector3_t */
+	public HmdVector3_t vDirection;
+	/**
+	 * @see ETrackingUniverseOrigin<br>
+	 * C type : ETrackingUniverseOrigin
+	 */
+	public int eOrigin;
+	public VROverlayIntersectionParams_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("vSource", "vDirection", "eOrigin");
+	}
+	/**
+	 * @param vSource C type : HmdVector3_t<br>
+	 * @param vDirection C type : HmdVector3_t<br>
+	 * @param eOrigin @see ETrackingUniverseOrigin<br>
+	 * C type : ETrackingUniverseOrigin
+	 */
+	public VROverlayIntersectionParams_t(HmdVector3_t vSource, HmdVector3_t vDirection, int eOrigin) {
+		super();
+		this.vSource = vSource;
+		this.vDirection = vDirection;
+		this.eOrigin = eOrigin;
+	}
+	public VROverlayIntersectionParams_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VROverlayIntersectionParams_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VROverlayIntersectionParams_t implements Structure.ByValue {
+		
+	};
+}

+ 47 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VROverlayIntersectionResults_t.java

@@ -0,0 +1,47 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1189</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VROverlayIntersectionResults_t extends Structure {
+	/** C type : HmdVector3_t */
+	public HmdVector3_t vPoint;
+	/** C type : HmdVector3_t */
+	public HmdVector3_t vNormal;
+	/** C type : HmdVector2_t */
+	public HmdVector2_t vUVs;
+	public float fDistance;
+	public VROverlayIntersectionResults_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("vPoint", "vNormal", "vUVs", "fDistance");
+	}
+	/**
+	 * @param vPoint C type : HmdVector3_t<br>
+	 * @param vNormal C type : HmdVector3_t<br>
+	 * @param vUVs C type : HmdVector2_t
+	 */
+	public VROverlayIntersectionResults_t(HmdVector3_t vPoint, HmdVector3_t vNormal, HmdVector2_t vUVs, float fDistance) {
+		super();
+		this.vPoint = vPoint;
+		this.vNormal = vNormal;
+		this.vUVs = vUVs;
+		this.fDistance = fDistance;
+	}
+	public VROverlayIntersectionResults_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VROverlayIntersectionResults_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VROverlayIntersectionResults_t implements Structure.ByValue {
+		
+	};
+}

+ 39 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VRTextureBounds_t.java

@@ -0,0 +1,39 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:980</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VRTextureBounds_t extends Structure {
+	public float uMin;
+	public float vMin;
+	public float uMax;
+	public float vMax;
+	public VRTextureBounds_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("uMin", "vMin", "uMax", "vMax");
+	}
+	public VRTextureBounds_t(float uMin, float vMin, float uMax, float vMax) {
+		super();
+		this.uMin = uMin;
+		this.vMin = vMin;
+		this.uMax = uMax;
+		this.vMax = vMax;
+	}
+	public VRTextureBounds_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VRTextureBounds_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VRTextureBounds_t implements Structure.ByValue {
+		
+	};
+}

+ 58 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VRVulkanTextureData_t.java

@@ -0,0 +1,58 @@
+package com.jme3.system.jopenvr;
+import com.jme3.system.jopenvr.JOpenVRLibrary.VkDevice_T;
+import com.jme3.system.jopenvr.JOpenVRLibrary.VkInstance_T;
+import com.jme3.system.jopenvr.JOpenVRLibrary.VkPhysicalDevice_T;
+import com.jme3.system.jopenvr.JOpenVRLibrary.VkQueue_T;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:996</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VRVulkanTextureData_t extends Structure {
+	public long m_nImage;
+	/**
+	 * struct VkDevice_T *<br>
+	 * C type : VkDevice_T*
+	 */
+	public VkDevice_T m_pDevice;
+	/**
+	 * struct VkPhysicalDevice_T *<br>
+	 * C type : VkPhysicalDevice_T*
+	 */
+	public VkPhysicalDevice_T m_pPhysicalDevice;
+	/**
+	 * struct VkInstance_T *<br>
+	 * C type : VkInstance_T*
+	 */
+	public VkInstance_T m_pInstance;
+	/**
+	 * struct VkQueue_T *<br>
+	 * C type : VkQueue_T*
+	 */
+	public VkQueue_T m_pQueue;
+	public int m_nQueueFamilyIndex;
+	public int m_nWidth;
+	public int m_nHeight;
+	public int m_nFormat;
+	public int m_nSampleCount;
+	public VRVulkanTextureData_t() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("m_nImage", "m_pDevice", "m_pPhysicalDevice", "m_pInstance", "m_pQueue", "m_nQueueFamilyIndex", "m_nWidth", "m_nHeight", "m_nFormat", "m_nSampleCount");
+	}
+	public VRVulkanTextureData_t(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VRVulkanTextureData_t implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VRVulkanTextureData_t implements Structure.ByValue {
+		
+	};
+}

+ 216 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VR_IVRApplications_FnTable.java

@@ -0,0 +1,216 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Callback;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import com.sun.jna.ptr.IntByReference;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1483</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VR_IVRApplications_FnTable extends Structure {
+	/** C type : AddApplicationManifest_callback* */
+	public VR_IVRApplications_FnTable.AddApplicationManifest_callback AddApplicationManifest;
+	/** C type : RemoveApplicationManifest_callback* */
+	public VR_IVRApplications_FnTable.RemoveApplicationManifest_callback RemoveApplicationManifest;
+	/** C type : IsApplicationInstalled_callback* */
+	public VR_IVRApplications_FnTable.IsApplicationInstalled_callback IsApplicationInstalled;
+	/** C type : GetApplicationCount_callback* */
+	public VR_IVRApplications_FnTable.GetApplicationCount_callback GetApplicationCount;
+	/** C type : GetApplicationKeyByIndex_callback* */
+	public VR_IVRApplications_FnTable.GetApplicationKeyByIndex_callback GetApplicationKeyByIndex;
+	/** C type : GetApplicationKeyByProcessId_callback* */
+	public VR_IVRApplications_FnTable.GetApplicationKeyByProcessId_callback GetApplicationKeyByProcessId;
+	/** C type : LaunchApplication_callback* */
+	public VR_IVRApplications_FnTable.LaunchApplication_callback LaunchApplication;
+	/** C type : LaunchTemplateApplication_callback* */
+	public VR_IVRApplications_FnTable.LaunchTemplateApplication_callback LaunchTemplateApplication;
+	/** C type : LaunchApplicationFromMimeType_callback* */
+	public VR_IVRApplications_FnTable.LaunchApplicationFromMimeType_callback LaunchApplicationFromMimeType;
+	/** C type : LaunchDashboardOverlay_callback* */
+	public VR_IVRApplications_FnTable.LaunchDashboardOverlay_callback LaunchDashboardOverlay;
+	/** C type : CancelApplicationLaunch_callback* */
+	public VR_IVRApplications_FnTable.CancelApplicationLaunch_callback CancelApplicationLaunch;
+	/** C type : IdentifyApplication_callback* */
+	public VR_IVRApplications_FnTable.IdentifyApplication_callback IdentifyApplication;
+	/** C type : GetApplicationProcessId_callback* */
+	public VR_IVRApplications_FnTable.GetApplicationProcessId_callback GetApplicationProcessId;
+	/** C type : GetApplicationsErrorNameFromEnum_callback* */
+	public VR_IVRApplications_FnTable.GetApplicationsErrorNameFromEnum_callback GetApplicationsErrorNameFromEnum;
+	/** C type : GetApplicationPropertyString_callback* */
+	public VR_IVRApplications_FnTable.GetApplicationPropertyString_callback GetApplicationPropertyString;
+	/** C type : GetApplicationPropertyBool_callback* */
+	public VR_IVRApplications_FnTable.GetApplicationPropertyBool_callback GetApplicationPropertyBool;
+	/** C type : GetApplicationPropertyUint64_callback* */
+	public VR_IVRApplications_FnTable.GetApplicationPropertyUint64_callback GetApplicationPropertyUint64;
+	/** C type : SetApplicationAutoLaunch_callback* */
+	public VR_IVRApplications_FnTable.SetApplicationAutoLaunch_callback SetApplicationAutoLaunch;
+	/** C type : GetApplicationAutoLaunch_callback* */
+	public VR_IVRApplications_FnTable.GetApplicationAutoLaunch_callback GetApplicationAutoLaunch;
+	/** C type : SetDefaultApplicationForMimeType_callback* */
+	public VR_IVRApplications_FnTable.SetDefaultApplicationForMimeType_callback SetDefaultApplicationForMimeType;
+	/** C type : GetDefaultApplicationForMimeType_callback* */
+	public VR_IVRApplications_FnTable.GetDefaultApplicationForMimeType_callback GetDefaultApplicationForMimeType;
+	/** C type : GetApplicationSupportedMimeTypes_callback* */
+	public VR_IVRApplications_FnTable.GetApplicationSupportedMimeTypes_callback GetApplicationSupportedMimeTypes;
+	/** C type : GetApplicationsThatSupportMimeType_callback* */
+	public VR_IVRApplications_FnTable.GetApplicationsThatSupportMimeType_callback GetApplicationsThatSupportMimeType;
+	/** C type : GetApplicationLaunchArguments_callback* */
+	public VR_IVRApplications_FnTable.GetApplicationLaunchArguments_callback GetApplicationLaunchArguments;
+	/** C type : GetStartingApplication_callback* */
+	public VR_IVRApplications_FnTable.GetStartingApplication_callback GetStartingApplication;
+	/** C type : GetTransitionState_callback* */
+	public VR_IVRApplications_FnTable.GetTransitionState_callback GetTransitionState;
+	/** C type : PerformApplicationPrelaunchCheck_callback* */
+	public VR_IVRApplications_FnTable.PerformApplicationPrelaunchCheck_callback PerformApplicationPrelaunchCheck;
+	/** C type : GetApplicationsTransitionStateNameFromEnum_callback* */
+	public VR_IVRApplications_FnTable.GetApplicationsTransitionStateNameFromEnum_callback GetApplicationsTransitionStateNameFromEnum;
+	/** C type : IsQuitUserPromptRequested_callback* */
+	public VR_IVRApplications_FnTable.IsQuitUserPromptRequested_callback IsQuitUserPromptRequested;
+	/** C type : LaunchInternalProcess_callback* */
+	public VR_IVRApplications_FnTable.LaunchInternalProcess_callback LaunchInternalProcess;
+	/** C type : GetCurrentSceneProcessId_callback* */
+	public VR_IVRApplications_FnTable.GetCurrentSceneProcessId_callback GetCurrentSceneProcessId;
+	/** <i>native declaration : headers\openvr_capi.h:1452</i> */
+	public interface AddApplicationManifest_callback extends Callback {
+		int apply(Pointer pchApplicationManifestFullPath, byte bTemporary);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1453</i> */
+	public interface RemoveApplicationManifest_callback extends Callback {
+		int apply(Pointer pchApplicationManifestFullPath);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1454</i> */
+	public interface IsApplicationInstalled_callback extends Callback {
+		byte apply(Pointer pchAppKey);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1455</i> */
+	public interface GetApplicationCount_callback extends Callback {
+		int apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1456</i> */
+	public interface GetApplicationKeyByIndex_callback extends Callback {
+		int apply(int unApplicationIndex, Pointer pchAppKeyBuffer, int unAppKeyBufferLen);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1457</i> */
+	public interface GetApplicationKeyByProcessId_callback extends Callback {
+		int apply(int unProcessId, Pointer pchAppKeyBuffer, int unAppKeyBufferLen);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1458</i> */
+	public interface LaunchApplication_callback extends Callback {
+		int apply(Pointer pchAppKey);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1459</i> */
+	public interface LaunchTemplateApplication_callback extends Callback {
+		int apply(Pointer pchTemplateAppKey, Pointer pchNewAppKey, AppOverrideKeys_t pKeys, int unKeys);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1460</i> */
+	public interface LaunchApplicationFromMimeType_callback extends Callback {
+		int apply(Pointer pchMimeType, Pointer pchArgs);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1461</i> */
+	public interface LaunchDashboardOverlay_callback extends Callback {
+		int apply(Pointer pchAppKey);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1462</i> */
+	public interface CancelApplicationLaunch_callback extends Callback {
+		byte apply(Pointer pchAppKey);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1463</i> */
+	public interface IdentifyApplication_callback extends Callback {
+		int apply(int unProcessId, Pointer pchAppKey);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1464</i> */
+	public interface GetApplicationProcessId_callback extends Callback {
+		int apply(Pointer pchAppKey);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1465</i> */
+	public interface GetApplicationsErrorNameFromEnum_callback extends Callback {
+		Pointer apply(int error);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1466</i> */
+	public interface GetApplicationPropertyString_callback extends Callback {
+		int apply(Pointer pchAppKey, int eProperty, Pointer pchPropertyValueBuffer, int unPropertyValueBufferLen, IntByReference peError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1467</i> */
+	public interface GetApplicationPropertyBool_callback extends Callback {
+		byte apply(Pointer pchAppKey, int eProperty, IntByReference peError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1468</i> */
+	public interface GetApplicationPropertyUint64_callback extends Callback {
+		long apply(Pointer pchAppKey, int eProperty, IntByReference peError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1469</i> */
+	public interface SetApplicationAutoLaunch_callback extends Callback {
+		int apply(Pointer pchAppKey, byte bAutoLaunch);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1470</i> */
+	public interface GetApplicationAutoLaunch_callback extends Callback {
+		byte apply(Pointer pchAppKey);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1471</i> */
+	public interface SetDefaultApplicationForMimeType_callback extends Callback {
+		int apply(Pointer pchAppKey, Pointer pchMimeType);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1472</i> */
+	public interface GetDefaultApplicationForMimeType_callback extends Callback {
+		byte apply(Pointer pchMimeType, Pointer pchAppKeyBuffer, int unAppKeyBufferLen);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1473</i> */
+	public interface GetApplicationSupportedMimeTypes_callback extends Callback {
+		byte apply(Pointer pchAppKey, Pointer pchMimeTypesBuffer, int unMimeTypesBuffer);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1474</i> */
+	public interface GetApplicationsThatSupportMimeType_callback extends Callback {
+		int apply(Pointer pchMimeType, Pointer pchAppKeysThatSupportBuffer, int unAppKeysThatSupportBuffer);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1475</i> */
+	public interface GetApplicationLaunchArguments_callback extends Callback {
+		int apply(int unHandle, Pointer pchArgs, int unArgs);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1476</i> */
+	public interface GetStartingApplication_callback extends Callback {
+		int apply(Pointer pchAppKeyBuffer, int unAppKeyBufferLen);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1477</i> */
+	public interface GetTransitionState_callback extends Callback {
+		int apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1478</i> */
+	public interface PerformApplicationPrelaunchCheck_callback extends Callback {
+		int apply(Pointer pchAppKey);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1479</i> */
+	public interface GetApplicationsTransitionStateNameFromEnum_callback extends Callback {
+		Pointer apply(int state);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1480</i> */
+	public interface IsQuitUserPromptRequested_callback extends Callback {
+		byte apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1481</i> */
+	public interface LaunchInternalProcess_callback extends Callback {
+		int apply(Pointer pchBinaryPath, Pointer pchArguments, Pointer pchWorkingDirectory);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1482</i> */
+	public interface GetCurrentSceneProcessId_callback extends Callback {
+		int apply();
+	};
+	public VR_IVRApplications_FnTable() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("AddApplicationManifest", "RemoveApplicationManifest", "IsApplicationInstalled", "GetApplicationCount", "GetApplicationKeyByIndex", "GetApplicationKeyByProcessId", "LaunchApplication", "LaunchTemplateApplication", "LaunchApplicationFromMimeType", "LaunchDashboardOverlay", "CancelApplicationLaunch", "IdentifyApplication", "GetApplicationProcessId", "GetApplicationsErrorNameFromEnum", "GetApplicationPropertyString", "GetApplicationPropertyBool", "GetApplicationPropertyUint64", "SetApplicationAutoLaunch", "GetApplicationAutoLaunch", "SetDefaultApplicationForMimeType", "GetDefaultApplicationForMimeType", "GetApplicationSupportedMimeTypes", "GetApplicationsThatSupportMimeType", "GetApplicationLaunchArguments", "GetStartingApplication", "GetTransitionState", "PerformApplicationPrelaunchCheck", "GetApplicationsTransitionStateNameFromEnum", "IsQuitUserPromptRequested", "LaunchInternalProcess", "GetCurrentSceneProcessId");
+	}
+	public VR_IVRApplications_FnTable(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VR_IVRApplications_FnTable implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VR_IVRApplications_FnTable implements Structure.ByValue {
+		
+	};
+}

+ 151 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VR_IVRChaperoneSetup_FnTable.java

@@ -0,0 +1,151 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Callback;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import com.sun.jna.ptr.FloatByReference;
+import com.sun.jna.ptr.IntByReference;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1543</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VR_IVRChaperoneSetup_FnTable extends Structure {
+	/** C type : CommitWorkingCopy_callback* */
+	public VR_IVRChaperoneSetup_FnTable.CommitWorkingCopy_callback CommitWorkingCopy;
+	/** C type : RevertWorkingCopy_callback* */
+	public VR_IVRChaperoneSetup_FnTable.RevertWorkingCopy_callback RevertWorkingCopy;
+	/** C type : GetWorkingPlayAreaSize_callback* */
+	public VR_IVRChaperoneSetup_FnTable.GetWorkingPlayAreaSize_callback GetWorkingPlayAreaSize;
+	/** C type : GetWorkingPlayAreaRect_callback* */
+	public VR_IVRChaperoneSetup_FnTable.GetWorkingPlayAreaRect_callback GetWorkingPlayAreaRect;
+	/** C type : GetWorkingCollisionBoundsInfo_callback* */
+	public VR_IVRChaperoneSetup_FnTable.GetWorkingCollisionBoundsInfo_callback GetWorkingCollisionBoundsInfo;
+	/** C type : GetLiveCollisionBoundsInfo_callback* */
+	public VR_IVRChaperoneSetup_FnTable.GetLiveCollisionBoundsInfo_callback GetLiveCollisionBoundsInfo;
+	/** C type : GetWorkingSeatedZeroPoseToRawTrackingPose_callback* */
+	public VR_IVRChaperoneSetup_FnTable.GetWorkingSeatedZeroPoseToRawTrackingPose_callback GetWorkingSeatedZeroPoseToRawTrackingPose;
+	/** C type : GetWorkingStandingZeroPoseToRawTrackingPose_callback* */
+	public VR_IVRChaperoneSetup_FnTable.GetWorkingStandingZeroPoseToRawTrackingPose_callback GetWorkingStandingZeroPoseToRawTrackingPose;
+	/** C type : SetWorkingPlayAreaSize_callback* */
+	public VR_IVRChaperoneSetup_FnTable.SetWorkingPlayAreaSize_callback SetWorkingPlayAreaSize;
+	/** C type : SetWorkingCollisionBoundsInfo_callback* */
+	public VR_IVRChaperoneSetup_FnTable.SetWorkingCollisionBoundsInfo_callback SetWorkingCollisionBoundsInfo;
+	/** C type : SetWorkingSeatedZeroPoseToRawTrackingPose_callback* */
+	public VR_IVRChaperoneSetup_FnTable.SetWorkingSeatedZeroPoseToRawTrackingPose_callback SetWorkingSeatedZeroPoseToRawTrackingPose;
+	/** C type : SetWorkingStandingZeroPoseToRawTrackingPose_callback* */
+	public VR_IVRChaperoneSetup_FnTable.SetWorkingStandingZeroPoseToRawTrackingPose_callback SetWorkingStandingZeroPoseToRawTrackingPose;
+	/** C type : ReloadFromDisk_callback* */
+	public VR_IVRChaperoneSetup_FnTable.ReloadFromDisk_callback ReloadFromDisk;
+	/** C type : GetLiveSeatedZeroPoseToRawTrackingPose_callback* */
+	public VR_IVRChaperoneSetup_FnTable.GetLiveSeatedZeroPoseToRawTrackingPose_callback GetLiveSeatedZeroPoseToRawTrackingPose;
+	/** C type : SetWorkingCollisionBoundsTagsInfo_callback* */
+	public VR_IVRChaperoneSetup_FnTable.SetWorkingCollisionBoundsTagsInfo_callback SetWorkingCollisionBoundsTagsInfo;
+	/** C type : GetLiveCollisionBoundsTagsInfo_callback* */
+	public VR_IVRChaperoneSetup_FnTable.GetLiveCollisionBoundsTagsInfo_callback GetLiveCollisionBoundsTagsInfo;
+	/** C type : SetWorkingPhysicalBoundsInfo_callback* */
+	public VR_IVRChaperoneSetup_FnTable.SetWorkingPhysicalBoundsInfo_callback SetWorkingPhysicalBoundsInfo;
+	/** C type : GetLivePhysicalBoundsInfo_callback* */
+	public VR_IVRChaperoneSetup_FnTable.GetLivePhysicalBoundsInfo_callback GetLivePhysicalBoundsInfo;
+	/** C type : ExportLiveToBuffer_callback* */
+	public VR_IVRChaperoneSetup_FnTable.ExportLiveToBuffer_callback ExportLiveToBuffer;
+	/** C type : ImportFromBufferToWorking_callback* */
+	public VR_IVRChaperoneSetup_FnTable.ImportFromBufferToWorking_callback ImportFromBufferToWorking;
+	/** <i>native declaration : headers\openvr_capi.h:1523</i> */
+	public interface CommitWorkingCopy_callback extends Callback {
+		byte apply(int configFile);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1524</i> */
+	public interface RevertWorkingCopy_callback extends Callback {
+		void apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1525</i> */
+	public interface GetWorkingPlayAreaSize_callback extends Callback {
+		byte apply(FloatByReference pSizeX, FloatByReference pSizeZ);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1526</i> */
+	public interface GetWorkingPlayAreaRect_callback extends Callback {
+		byte apply(HmdQuad_t rect);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1527</i> */
+	public interface GetWorkingCollisionBoundsInfo_callback extends Callback {
+		byte apply(HmdQuad_t pQuadsBuffer, IntByReference punQuadsCount);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1528</i> */
+	public interface GetLiveCollisionBoundsInfo_callback extends Callback {
+		byte apply(HmdQuad_t pQuadsBuffer, IntByReference punQuadsCount);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1529</i> */
+	public interface GetWorkingSeatedZeroPoseToRawTrackingPose_callback extends Callback {
+		byte apply(HmdMatrix34_t pmatSeatedZeroPoseToRawTrackingPose);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1530</i> */
+	public interface GetWorkingStandingZeroPoseToRawTrackingPose_callback extends Callback {
+		byte apply(HmdMatrix34_t pmatStandingZeroPoseToRawTrackingPose);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1531</i> */
+	public interface SetWorkingPlayAreaSize_callback extends Callback {
+		void apply(float sizeX, float sizeZ);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1532</i> */
+	public interface SetWorkingCollisionBoundsInfo_callback extends Callback {
+		void apply(HmdQuad_t pQuadsBuffer, int unQuadsCount);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1533</i> */
+	public interface SetWorkingSeatedZeroPoseToRawTrackingPose_callback extends Callback {
+		void apply(HmdMatrix34_t pMatSeatedZeroPoseToRawTrackingPose);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1534</i> */
+	public interface SetWorkingStandingZeroPoseToRawTrackingPose_callback extends Callback {
+		void apply(HmdMatrix34_t pMatStandingZeroPoseToRawTrackingPose);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1535</i> */
+	public interface ReloadFromDisk_callback extends Callback {
+		void apply(int configFile);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1536</i> */
+	public interface GetLiveSeatedZeroPoseToRawTrackingPose_callback extends Callback {
+		byte apply(HmdMatrix34_t pmatSeatedZeroPoseToRawTrackingPose);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1537</i> */
+	public interface SetWorkingCollisionBoundsTagsInfo_callback extends Callback {
+		void apply(Pointer pTagsBuffer, int unTagCount);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1538</i> */
+	public interface GetLiveCollisionBoundsTagsInfo_callback extends Callback {
+		byte apply(Pointer pTagsBuffer, IntByReference punTagCount);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1539</i> */
+	public interface SetWorkingPhysicalBoundsInfo_callback extends Callback {
+		byte apply(HmdQuad_t pQuadsBuffer, int unQuadsCount);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1540</i> */
+	public interface GetLivePhysicalBoundsInfo_callback extends Callback {
+		byte apply(HmdQuad_t pQuadsBuffer, IntByReference punQuadsCount);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1541</i> */
+	public interface ExportLiveToBuffer_callback extends Callback {
+		byte apply(Pointer pBuffer, IntByReference pnBufferLength);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1542</i> */
+	public interface ImportFromBufferToWorking_callback extends Callback {
+		byte apply(Pointer pBuffer, int nImportFlags);
+	};
+	public VR_IVRChaperoneSetup_FnTable() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("CommitWorkingCopy", "RevertWorkingCopy", "GetWorkingPlayAreaSize", "GetWorkingPlayAreaRect", "GetWorkingCollisionBoundsInfo", "GetLiveCollisionBoundsInfo", "GetWorkingSeatedZeroPoseToRawTrackingPose", "GetWorkingStandingZeroPoseToRawTrackingPose", "SetWorkingPlayAreaSize", "SetWorkingCollisionBoundsInfo", "SetWorkingSeatedZeroPoseToRawTrackingPose", "SetWorkingStandingZeroPoseToRawTrackingPose", "ReloadFromDisk", "GetLiveSeatedZeroPoseToRawTrackingPose", "SetWorkingCollisionBoundsTagsInfo", "GetLiveCollisionBoundsTagsInfo", "SetWorkingPhysicalBoundsInfo", "GetLivePhysicalBoundsInfo", "ExportLiveToBuffer", "ImportFromBufferToWorking");
+	}
+	public VR_IVRChaperoneSetup_FnTable(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VR_IVRChaperoneSetup_FnTable implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VR_IVRChaperoneSetup_FnTable implements Structure.ByValue {
+		
+	};
+}

+ 99 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VR_IVRChaperone_FnTable.java

@@ -0,0 +1,99 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Callback;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import com.sun.jna.ptr.FloatByReference;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1501</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VR_IVRChaperone_FnTable extends Structure {
+	/** C type : GetCalibrationState_callback* */
+	public VR_IVRChaperone_FnTable.GetCalibrationState_callback GetCalibrationState;
+	/** C type : GetPlayAreaSize_callback* */
+	public VR_IVRChaperone_FnTable.GetPlayAreaSize_callback GetPlayAreaSize;
+	/** C type : GetPlayAreaRect_callback* */
+	public VR_IVRChaperone_FnTable.GetPlayAreaRect_callback GetPlayAreaRect;
+	/** C type : ReloadInfo_callback* */
+	public VR_IVRChaperone_FnTable.ReloadInfo_callback ReloadInfo;
+	/** C type : SetSceneColor_callback* */
+	public VR_IVRChaperone_FnTable.SetSceneColor_callback SetSceneColor;
+	/** C type : GetBoundsColor_callback* */
+	public VR_IVRChaperone_FnTable.GetBoundsColor_callback GetBoundsColor;
+	/** C type : AreBoundsVisible_callback* */
+	public VR_IVRChaperone_FnTable.AreBoundsVisible_callback AreBoundsVisible;
+	/** C type : ForceBoundsVisible_callback* */
+	public VR_IVRChaperone_FnTable.ForceBoundsVisible_callback ForceBoundsVisible;
+	/** <i>native declaration : headers\openvr_capi.h:1493</i> */
+	public interface GetCalibrationState_callback extends Callback {
+		int apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1494</i> */
+	public interface GetPlayAreaSize_callback extends Callback {
+		byte apply(FloatByReference pSizeX, FloatByReference pSizeZ);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1495</i> */
+	public interface GetPlayAreaRect_callback extends Callback {
+		byte apply(HmdQuad_t rect);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1496</i> */
+	public interface ReloadInfo_callback extends Callback {
+		void apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1497</i> */
+	public interface SetSceneColor_callback extends Callback {
+		void apply(HmdColor_t.ByValue color);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1498</i> */
+	public interface GetBoundsColor_callback extends Callback {
+		void apply(HmdColor_t pOutputColorArray, int nNumOutputColors, float flCollisionBoundsFadeDistance, HmdColor_t pOutputCameraColor);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1499</i> */
+	public interface AreBoundsVisible_callback extends Callback {
+		byte apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1500</i> */
+	public interface ForceBoundsVisible_callback extends Callback {
+		void apply(byte bForce);
+	};
+	public VR_IVRChaperone_FnTable() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("GetCalibrationState", "GetPlayAreaSize", "GetPlayAreaRect", "ReloadInfo", "SetSceneColor", "GetBoundsColor", "AreBoundsVisible", "ForceBoundsVisible");
+	}
+	/**
+	 * @param GetCalibrationState C type : GetCalibrationState_callback*<br>
+	 * @param GetPlayAreaSize C type : GetPlayAreaSize_callback*<br>
+	 * @param GetPlayAreaRect C type : GetPlayAreaRect_callback*<br>
+	 * @param ReloadInfo C type : ReloadInfo_callback*<br>
+	 * @param SetSceneColor C type : SetSceneColor_callback*<br>
+	 * @param GetBoundsColor C type : GetBoundsColor_callback*<br>
+	 * @param AreBoundsVisible C type : AreBoundsVisible_callback*<br>
+	 * @param ForceBoundsVisible C type : ForceBoundsVisible_callback*
+	 */
+	public VR_IVRChaperone_FnTable(VR_IVRChaperone_FnTable.GetCalibrationState_callback GetCalibrationState, VR_IVRChaperone_FnTable.GetPlayAreaSize_callback GetPlayAreaSize, VR_IVRChaperone_FnTable.GetPlayAreaRect_callback GetPlayAreaRect, VR_IVRChaperone_FnTable.ReloadInfo_callback ReloadInfo, VR_IVRChaperone_FnTable.SetSceneColor_callback SetSceneColor, VR_IVRChaperone_FnTable.GetBoundsColor_callback GetBoundsColor, VR_IVRChaperone_FnTable.AreBoundsVisible_callback AreBoundsVisible, VR_IVRChaperone_FnTable.ForceBoundsVisible_callback ForceBoundsVisible) {
+		super();
+		this.GetCalibrationState = GetCalibrationState;
+		this.GetPlayAreaSize = GetPlayAreaSize;
+		this.GetPlayAreaRect = GetPlayAreaRect;
+		this.ReloadInfo = ReloadInfo;
+		this.SetSceneColor = SetSceneColor;
+		this.GetBoundsColor = GetBoundsColor;
+		this.AreBoundsVisible = AreBoundsVisible;
+		this.ForceBoundsVisible = ForceBoundsVisible;
+	}
+	public VR_IVRChaperone_FnTable(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VR_IVRChaperone_FnTable implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VR_IVRChaperone_FnTable implements Structure.ByValue {
+		
+	};
+}

+ 278 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VR_IVRCompositor_FnTable.java

@@ -0,0 +1,278 @@
+package com.jme3.system.jopenvr;
+import com.jme3.system.jopenvr.JOpenVRLibrary.VkPhysicalDevice_T;
+import com.sun.jna.Callback;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import com.sun.jna.ptr.IntByReference;
+import com.sun.jna.ptr.PointerByReference;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1627</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VR_IVRCompositor_FnTable extends Structure {
+	/** C type : SetTrackingSpace_callback* */
+	public VR_IVRCompositor_FnTable.SetTrackingSpace_callback SetTrackingSpace;
+	/** C type : GetTrackingSpace_callback* */
+	public VR_IVRCompositor_FnTable.GetTrackingSpace_callback GetTrackingSpace;
+	/** C type : WaitGetPoses_callback* */
+	public VR_IVRCompositor_FnTable.WaitGetPoses_callback WaitGetPoses;
+	/** C type : GetLastPoses_callback* */
+	public VR_IVRCompositor_FnTable.GetLastPoses_callback GetLastPoses;
+	/** C type : GetLastPoseForTrackedDeviceIndex_callback* */
+	public VR_IVRCompositor_FnTable.GetLastPoseForTrackedDeviceIndex_callback GetLastPoseForTrackedDeviceIndex;
+	/** C type : Submit_callback* */
+	public VR_IVRCompositor_FnTable.Submit_callback Submit;
+	/** C type : ClearLastSubmittedFrame_callback* */
+	public VR_IVRCompositor_FnTable.ClearLastSubmittedFrame_callback ClearLastSubmittedFrame;
+	/** C type : PostPresentHandoff_callback* */
+	public VR_IVRCompositor_FnTable.PostPresentHandoff_callback PostPresentHandoff;
+	/** C type : GetFrameTiming_callback* */
+	public VR_IVRCompositor_FnTable.GetFrameTiming_callback GetFrameTiming;
+	/** C type : GetFrameTimings_callback* */
+	public VR_IVRCompositor_FnTable.GetFrameTimings_callback GetFrameTimings;
+	/** C type : GetFrameTimeRemaining_callback* */
+	public VR_IVRCompositor_FnTable.GetFrameTimeRemaining_callback GetFrameTimeRemaining;
+	/** C type : GetCumulativeStats_callback* */
+	public VR_IVRCompositor_FnTable.GetCumulativeStats_callback GetCumulativeStats;
+	/** C type : FadeToColor_callback* */
+	public VR_IVRCompositor_FnTable.FadeToColor_callback FadeToColor;
+	/** C type : GetCurrentFadeColor_callback* */
+	public VR_IVRCompositor_FnTable.GetCurrentFadeColor_callback GetCurrentFadeColor;
+	/** C type : FadeGrid_callback* */
+	public VR_IVRCompositor_FnTable.FadeGrid_callback FadeGrid;
+	/** C type : GetCurrentGridAlpha_callback* */
+	public VR_IVRCompositor_FnTable.GetCurrentGridAlpha_callback GetCurrentGridAlpha;
+	/** C type : SetSkyboxOverride_callback* */
+	public VR_IVRCompositor_FnTable.SetSkyboxOverride_callback SetSkyboxOverride;
+	/** C type : ClearSkyboxOverride_callback* */
+	public VR_IVRCompositor_FnTable.ClearSkyboxOverride_callback ClearSkyboxOverride;
+	/** C type : CompositorBringToFront_callback* */
+	public VR_IVRCompositor_FnTable.CompositorBringToFront_callback CompositorBringToFront;
+	/** C type : CompositorGoToBack_callback* */
+	public VR_IVRCompositor_FnTable.CompositorGoToBack_callback CompositorGoToBack;
+	/** C type : CompositorQuit_callback* */
+	public VR_IVRCompositor_FnTable.CompositorQuit_callback CompositorQuit;
+	/** C type : IsFullscreen_callback* */
+	public VR_IVRCompositor_FnTable.IsFullscreen_callback IsFullscreen;
+	/** C type : GetCurrentSceneFocusProcess_callback* */
+	public VR_IVRCompositor_FnTable.GetCurrentSceneFocusProcess_callback GetCurrentSceneFocusProcess;
+	/** C type : GetLastFrameRenderer_callback* */
+	public VR_IVRCompositor_FnTable.GetLastFrameRenderer_callback GetLastFrameRenderer;
+	/** C type : CanRenderScene_callback* */
+	public VR_IVRCompositor_FnTable.CanRenderScene_callback CanRenderScene;
+	/** C type : ShowMirrorWindow_callback* */
+	public VR_IVRCompositor_FnTable.ShowMirrorWindow_callback ShowMirrorWindow;
+	/** C type : HideMirrorWindow_callback* */
+	public VR_IVRCompositor_FnTable.HideMirrorWindow_callback HideMirrorWindow;
+	/** C type : IsMirrorWindowVisible_callback* */
+	public VR_IVRCompositor_FnTable.IsMirrorWindowVisible_callback IsMirrorWindowVisible;
+	/** C type : CompositorDumpImages_callback* */
+	public VR_IVRCompositor_FnTable.CompositorDumpImages_callback CompositorDumpImages;
+	/** C type : ShouldAppRenderWithLowResources_callback* */
+	public VR_IVRCompositor_FnTable.ShouldAppRenderWithLowResources_callback ShouldAppRenderWithLowResources;
+	/** C type : ForceInterleavedReprojectionOn_callback* */
+	public VR_IVRCompositor_FnTable.ForceInterleavedReprojectionOn_callback ForceInterleavedReprojectionOn;
+	/** C type : ForceReconnectProcess_callback* */
+	public VR_IVRCompositor_FnTable.ForceReconnectProcess_callback ForceReconnectProcess;
+	/** C type : SuspendRendering_callback* */
+	public VR_IVRCompositor_FnTable.SuspendRendering_callback SuspendRendering;
+	/** C type : GetMirrorTextureD3D11_callback* */
+	public VR_IVRCompositor_FnTable.GetMirrorTextureD3D11_callback GetMirrorTextureD3D11;
+	/** C type : ReleaseMirrorTextureD3D11_callback* */
+	public VR_IVRCompositor_FnTable.ReleaseMirrorTextureD3D11_callback ReleaseMirrorTextureD3D11;
+	/** C type : GetMirrorTextureGL_callback* */
+	public VR_IVRCompositor_FnTable.GetMirrorTextureGL_callback GetMirrorTextureGL;
+	/** C type : ReleaseSharedGLTexture_callback* */
+	public VR_IVRCompositor_FnTable.ReleaseSharedGLTexture_callback ReleaseSharedGLTexture;
+	/** C type : LockGLSharedTextureForAccess_callback* */
+	public VR_IVRCompositor_FnTable.LockGLSharedTextureForAccess_callback LockGLSharedTextureForAccess;
+	/** C type : UnlockGLSharedTextureForAccess_callback* */
+	public VR_IVRCompositor_FnTable.UnlockGLSharedTextureForAccess_callback UnlockGLSharedTextureForAccess;
+	/** C type : GetVulkanInstanceExtensionsRequired_callback* */
+	public VR_IVRCompositor_FnTable.GetVulkanInstanceExtensionsRequired_callback GetVulkanInstanceExtensionsRequired;
+	/** C type : GetVulkanDeviceExtensionsRequired_callback* */
+	public VR_IVRCompositor_FnTable.GetVulkanDeviceExtensionsRequired_callback GetVulkanDeviceExtensionsRequired;
+	/** <i>native declaration : headers\openvr_capi.h:1586</i> */
+	public interface SetTrackingSpace_callback extends Callback {
+		void apply(int eOrigin);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1587</i> */
+	public interface GetTrackingSpace_callback extends Callback {
+		int apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1588</i> */
+	public interface WaitGetPoses_callback extends Callback {
+		int apply(TrackedDevicePose_t pRenderPoseArray, int unRenderPoseArrayCount, TrackedDevicePose_t pGamePoseArray, int unGamePoseArrayCount);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1589</i> */
+	public interface GetLastPoses_callback extends Callback {
+		int apply(TrackedDevicePose_t pRenderPoseArray, int unRenderPoseArrayCount, TrackedDevicePose_t pGamePoseArray, int unGamePoseArrayCount);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1590</i> */
+	public interface GetLastPoseForTrackedDeviceIndex_callback extends Callback {
+		int apply(int unDeviceIndex, TrackedDevicePose_t pOutputPose, TrackedDevicePose_t pOutputGamePose);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1591</i> */
+	public interface Submit_callback extends Callback {
+		int apply(int eEye, Texture_t pTexture, VRTextureBounds_t pBounds, int nSubmitFlags);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1592</i> */
+	public interface ClearLastSubmittedFrame_callback extends Callback {
+		void apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1593</i> */
+	public interface PostPresentHandoff_callback extends Callback {
+		void apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1594</i> */
+	public interface GetFrameTiming_callback extends Callback {
+		byte apply(Compositor_FrameTiming pTiming, int unFramesAgo);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1595</i> */
+	public interface GetFrameTimings_callback extends Callback {
+		int apply(Compositor_FrameTiming pTiming, int nFrames);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1596</i> */
+	public interface GetFrameTimeRemaining_callback extends Callback {
+		float apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1597</i> */
+	public interface GetCumulativeStats_callback extends Callback {
+		void apply(Compositor_CumulativeStats pStats, int nStatsSizeInBytes);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1598</i> */
+	public interface FadeToColor_callback extends Callback {
+		void apply(float fSeconds, float fRed, float fGreen, float fBlue, float fAlpha, byte bBackground);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1599</i> */
+	public interface GetCurrentFadeColor_callback extends Callback {
+		com.jme3.system.jopenvr.HmdColor_t.ByValue apply(byte bBackground);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1600</i> */
+	public interface FadeGrid_callback extends Callback {
+		void apply(float fSeconds, byte bFadeIn);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1601</i> */
+	public interface GetCurrentGridAlpha_callback extends Callback {
+		float apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1602</i> */
+	public interface SetSkyboxOverride_callback extends Callback {
+		int apply(Texture_t pTextures, int unTextureCount);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1603</i> */
+	public interface ClearSkyboxOverride_callback extends Callback {
+		void apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1604</i> */
+	public interface CompositorBringToFront_callback extends Callback {
+		void apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1605</i> */
+	public interface CompositorGoToBack_callback extends Callback {
+		void apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1606</i> */
+	public interface CompositorQuit_callback extends Callback {
+		void apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1607</i> */
+	public interface IsFullscreen_callback extends Callback {
+		byte apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1608</i> */
+	public interface GetCurrentSceneFocusProcess_callback extends Callback {
+		int apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1609</i> */
+	public interface GetLastFrameRenderer_callback extends Callback {
+		int apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1610</i> */
+	public interface CanRenderScene_callback extends Callback {
+		byte apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1611</i> */
+	public interface ShowMirrorWindow_callback extends Callback {
+		void apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1612</i> */
+	public interface HideMirrorWindow_callback extends Callback {
+		void apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1613</i> */
+	public interface IsMirrorWindowVisible_callback extends Callback {
+		byte apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1614</i> */
+	public interface CompositorDumpImages_callback extends Callback {
+		void apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1615</i> */
+	public interface ShouldAppRenderWithLowResources_callback extends Callback {
+		byte apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1616</i> */
+	public interface ForceInterleavedReprojectionOn_callback extends Callback {
+		void apply(byte bOverride);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1617</i> */
+	public interface ForceReconnectProcess_callback extends Callback {
+		void apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1618</i> */
+	public interface SuspendRendering_callback extends Callback {
+		void apply(byte bSuspend);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1619</i> */
+	public interface GetMirrorTextureD3D11_callback extends Callback {
+		int apply(int eEye, Pointer pD3D11DeviceOrResource, PointerByReference ppD3D11ShaderResourceView);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1620</i> */
+	public interface ReleaseMirrorTextureD3D11_callback extends Callback {
+		void apply(Pointer pD3D11ShaderResourceView);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1621</i> */
+	public interface GetMirrorTextureGL_callback extends Callback {
+		int apply(int eEye, IntByReference pglTextureId, PointerByReference pglSharedTextureHandle);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1622</i> */
+	public interface ReleaseSharedGLTexture_callback extends Callback {
+		byte apply(int glTextureId, Pointer glSharedTextureHandle);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1623</i> */
+	public interface LockGLSharedTextureForAccess_callback extends Callback {
+		void apply(Pointer glSharedTextureHandle);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1624</i> */
+	public interface UnlockGLSharedTextureForAccess_callback extends Callback {
+		void apply(Pointer glSharedTextureHandle);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1625</i> */
+	public interface GetVulkanInstanceExtensionsRequired_callback extends Callback {
+		int apply(Pointer pchValue, int unBufferSize);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1626</i> */
+	public interface GetVulkanDeviceExtensionsRequired_callback extends Callback {
+		int apply(VkPhysicalDevice_T pPhysicalDevice, Pointer pchValue, int unBufferSize);
+	};
+	public VR_IVRCompositor_FnTable() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("SetTrackingSpace", "GetTrackingSpace", "WaitGetPoses", "GetLastPoses", "GetLastPoseForTrackedDeviceIndex", "Submit", "ClearLastSubmittedFrame", "PostPresentHandoff", "GetFrameTiming", "GetFrameTimings", "GetFrameTimeRemaining", "GetCumulativeStats", "FadeToColor", "GetCurrentFadeColor", "FadeGrid", "GetCurrentGridAlpha", "SetSkyboxOverride", "ClearSkyboxOverride", "CompositorBringToFront", "CompositorGoToBack", "CompositorQuit", "IsFullscreen", "GetCurrentSceneFocusProcess", "GetLastFrameRenderer", "CanRenderScene", "ShowMirrorWindow", "HideMirrorWindow", "IsMirrorWindowVisible", "CompositorDumpImages", "ShouldAppRenderWithLowResources", "ForceInterleavedReprojectionOn", "ForceReconnectProcess", "SuspendRendering", "GetMirrorTextureD3D11", "ReleaseMirrorTextureD3D11", "GetMirrorTextureGL", "ReleaseSharedGLTexture", "LockGLSharedTextureForAccess", "UnlockGLSharedTextureForAccess", "GetVulkanInstanceExtensionsRequired", "GetVulkanDeviceExtensionsRequired");
+	}
+	public VR_IVRCompositor_FnTable(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VR_IVRCompositor_FnTable implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VR_IVRCompositor_FnTable implements Structure.ByValue {
+		
+	};
+}

+ 59 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VR_IVRExtendedDisplay_FnTable.java

@@ -0,0 +1,59 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Callback;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import com.sun.jna.ptr.IntByReference;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1393</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VR_IVRExtendedDisplay_FnTable extends Structure {
+	/** C type : GetWindowBounds_callback* */
+	public VR_IVRExtendedDisplay_FnTable.GetWindowBounds_callback GetWindowBounds;
+	/** C type : GetEyeOutputViewport_callback* */
+	public VR_IVRExtendedDisplay_FnTable.GetEyeOutputViewport_callback GetEyeOutputViewport;
+	/** C type : GetDXGIOutputInfo_callback* */
+	public VR_IVRExtendedDisplay_FnTable.GetDXGIOutputInfo_callback GetDXGIOutputInfo;
+	/** <i>native declaration : headers\openvr_capi.h:1390</i> */
+	public interface GetWindowBounds_callback extends Callback {
+		void apply(IntByReference pnX, IntByReference pnY, IntByReference pnWidth, IntByReference pnHeight);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1391</i> */
+	public interface GetEyeOutputViewport_callback extends Callback {
+		void apply(int eEye, IntByReference pnX, IntByReference pnY, IntByReference pnWidth, IntByReference pnHeight);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1392</i> */
+	public interface GetDXGIOutputInfo_callback extends Callback {
+		void apply(IntByReference pnAdapterIndex, IntByReference pnAdapterOutputIndex);
+	};
+	public VR_IVRExtendedDisplay_FnTable() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("GetWindowBounds", "GetEyeOutputViewport", "GetDXGIOutputInfo");
+	}
+	/**
+	 * @param GetWindowBounds C type : GetWindowBounds_callback*<br>
+	 * @param GetEyeOutputViewport C type : GetEyeOutputViewport_callback*<br>
+	 * @param GetDXGIOutputInfo C type : GetDXGIOutputInfo_callback*
+	 */
+	public VR_IVRExtendedDisplay_FnTable(VR_IVRExtendedDisplay_FnTable.GetWindowBounds_callback GetWindowBounds, VR_IVRExtendedDisplay_FnTable.GetEyeOutputViewport_callback GetEyeOutputViewport, VR_IVRExtendedDisplay_FnTable.GetDXGIOutputInfo_callback GetDXGIOutputInfo) {
+		super();
+		this.GetWindowBounds = GetWindowBounds;
+		this.GetEyeOutputViewport = GetEyeOutputViewport;
+		this.GetDXGIOutputInfo = GetDXGIOutputInfo;
+	}
+	public VR_IVRExtendedDisplay_FnTable(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VR_IVRExtendedDisplay_FnTable implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VR_IVRExtendedDisplay_FnTable implements Structure.ByValue {
+		
+	};
+}

+ 51 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VR_IVRNotifications_FnTable.java

@@ -0,0 +1,51 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Callback;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import com.sun.jna.ptr.IntByReference;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1823</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VR_IVRNotifications_FnTable extends Structure {
+	/** C type : CreateNotification_callback* */
+	public VR_IVRNotifications_FnTable.CreateNotification_callback CreateNotification;
+	/** C type : RemoveNotification_callback* */
+	public VR_IVRNotifications_FnTable.RemoveNotification_callback RemoveNotification;
+	/** <i>native declaration : headers\openvr_capi.h:1821</i> */
+	public interface CreateNotification_callback extends Callback {
+		int apply(long ulOverlayHandle, long ulUserValue, int type, Pointer pchText, int style, NotificationBitmap_t pImage, IntByReference pNotificationId);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1822</i> */
+	public interface RemoveNotification_callback extends Callback {
+		int apply(int notificationId);
+	};
+	public VR_IVRNotifications_FnTable() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("CreateNotification", "RemoveNotification");
+	}
+	/**
+	 * @param CreateNotification C type : CreateNotification_callback*<br>
+	 * @param RemoveNotification C type : RemoveNotification_callback*
+	 */
+	public VR_IVRNotifications_FnTable(VR_IVRNotifications_FnTable.CreateNotification_callback CreateNotification, VR_IVRNotifications_FnTable.RemoveNotification_callback RemoveNotification) {
+		super();
+		this.CreateNotification = CreateNotification;
+		this.RemoveNotification = RemoveNotification;
+	}
+	public VR_IVRNotifications_FnTable(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VR_IVRNotifications_FnTable implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VR_IVRNotifications_FnTable implements Structure.ByValue {
+		
+	};
+}

+ 483 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VR_IVROverlay_FnTable.java

@@ -0,0 +1,483 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Callback;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import com.sun.jna.ptr.FloatByReference;
+import com.sun.jna.ptr.IntByReference;
+import com.sun.jna.ptr.LongByReference;
+import com.sun.jna.ptr.PointerByReference;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1779</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VR_IVROverlay_FnTable extends Structure {
+	/** C type : FindOverlay_callback* */
+	public VR_IVROverlay_FnTable.FindOverlay_callback FindOverlay;
+	/** C type : CreateOverlay_callback* */
+	public VR_IVROverlay_FnTable.CreateOverlay_callback CreateOverlay;
+	/** C type : DestroyOverlay_callback* */
+	public VR_IVROverlay_FnTable.DestroyOverlay_callback DestroyOverlay;
+	/** C type : SetHighQualityOverlay_callback* */
+	public VR_IVROverlay_FnTable.SetHighQualityOverlay_callback SetHighQualityOverlay;
+	/** C type : GetHighQualityOverlay_callback* */
+	public VR_IVROverlay_FnTable.GetHighQualityOverlay_callback GetHighQualityOverlay;
+	/** C type : GetOverlayKey_callback* */
+	public VR_IVROverlay_FnTable.GetOverlayKey_callback GetOverlayKey;
+	/** C type : GetOverlayName_callback* */
+	public VR_IVROverlay_FnTable.GetOverlayName_callback GetOverlayName;
+	/** C type : GetOverlayImageData_callback* */
+	public VR_IVROverlay_FnTable.GetOverlayImageData_callback GetOverlayImageData;
+	/** C type : GetOverlayErrorNameFromEnum_callback* */
+	public VR_IVROverlay_FnTable.GetOverlayErrorNameFromEnum_callback GetOverlayErrorNameFromEnum;
+	/** C type : SetOverlayRenderingPid_callback* */
+	public VR_IVROverlay_FnTable.SetOverlayRenderingPid_callback SetOverlayRenderingPid;
+	/** C type : GetOverlayRenderingPid_callback* */
+	public VR_IVROverlay_FnTable.GetOverlayRenderingPid_callback GetOverlayRenderingPid;
+	/** C type : SetOverlayFlag_callback* */
+	public VR_IVROverlay_FnTable.SetOverlayFlag_callback SetOverlayFlag;
+	/** C type : GetOverlayFlag_callback* */
+	public VR_IVROverlay_FnTable.GetOverlayFlag_callback GetOverlayFlag;
+	/** C type : SetOverlayColor_callback* */
+	public VR_IVROverlay_FnTable.SetOverlayColor_callback SetOverlayColor;
+	/** C type : GetOverlayColor_callback* */
+	public VR_IVROverlay_FnTable.GetOverlayColor_callback GetOverlayColor;
+	/** C type : SetOverlayAlpha_callback* */
+	public VR_IVROverlay_FnTable.SetOverlayAlpha_callback SetOverlayAlpha;
+	/** C type : GetOverlayAlpha_callback* */
+	public VR_IVROverlay_FnTable.GetOverlayAlpha_callback GetOverlayAlpha;
+	/** C type : SetOverlayTexelAspect_callback* */
+	public VR_IVROverlay_FnTable.SetOverlayTexelAspect_callback SetOverlayTexelAspect;
+	/** C type : GetOverlayTexelAspect_callback* */
+	public VR_IVROverlay_FnTable.GetOverlayTexelAspect_callback GetOverlayTexelAspect;
+	/** C type : SetOverlaySortOrder_callback* */
+	public VR_IVROverlay_FnTable.SetOverlaySortOrder_callback SetOverlaySortOrder;
+	/** C type : GetOverlaySortOrder_callback* */
+	public VR_IVROverlay_FnTable.GetOverlaySortOrder_callback GetOverlaySortOrder;
+	/** C type : SetOverlayWidthInMeters_callback* */
+	public VR_IVROverlay_FnTable.SetOverlayWidthInMeters_callback SetOverlayWidthInMeters;
+	/** C type : GetOverlayWidthInMeters_callback* */
+	public VR_IVROverlay_FnTable.GetOverlayWidthInMeters_callback GetOverlayWidthInMeters;
+	/** C type : SetOverlayAutoCurveDistanceRangeInMeters_callback* */
+	public VR_IVROverlay_FnTable.SetOverlayAutoCurveDistanceRangeInMeters_callback SetOverlayAutoCurveDistanceRangeInMeters;
+	/** C type : GetOverlayAutoCurveDistanceRangeInMeters_callback* */
+	public VR_IVROverlay_FnTable.GetOverlayAutoCurveDistanceRangeInMeters_callback GetOverlayAutoCurveDistanceRangeInMeters;
+	/** C type : SetOverlayTextureColorSpace_callback* */
+	public VR_IVROverlay_FnTable.SetOverlayTextureColorSpace_callback SetOverlayTextureColorSpace;
+	/** C type : GetOverlayTextureColorSpace_callback* */
+	public VR_IVROverlay_FnTable.GetOverlayTextureColorSpace_callback GetOverlayTextureColorSpace;
+	/** C type : SetOverlayTextureBounds_callback* */
+	public VR_IVROverlay_FnTable.SetOverlayTextureBounds_callback SetOverlayTextureBounds;
+	/** C type : GetOverlayTextureBounds_callback* */
+	public VR_IVROverlay_FnTable.GetOverlayTextureBounds_callback GetOverlayTextureBounds;
+	/** C type : GetOverlayTransformType_callback* */
+	public VR_IVROverlay_FnTable.GetOverlayTransformType_callback GetOverlayTransformType;
+	/** C type : SetOverlayTransformAbsolute_callback* */
+	public VR_IVROverlay_FnTable.SetOverlayTransformAbsolute_callback SetOverlayTransformAbsolute;
+	/** C type : GetOverlayTransformAbsolute_callback* */
+	public VR_IVROverlay_FnTable.GetOverlayTransformAbsolute_callback GetOverlayTransformAbsolute;
+	/** C type : SetOverlayTransformTrackedDeviceRelative_callback* */
+	public VR_IVROverlay_FnTable.SetOverlayTransformTrackedDeviceRelative_callback SetOverlayTransformTrackedDeviceRelative;
+	/** C type : GetOverlayTransformTrackedDeviceRelative_callback* */
+	public VR_IVROverlay_FnTable.GetOverlayTransformTrackedDeviceRelative_callback GetOverlayTransformTrackedDeviceRelative;
+	/** C type : SetOverlayTransformTrackedDeviceComponent_callback* */
+	public VR_IVROverlay_FnTable.SetOverlayTransformTrackedDeviceComponent_callback SetOverlayTransformTrackedDeviceComponent;
+	/** C type : GetOverlayTransformTrackedDeviceComponent_callback* */
+	public VR_IVROverlay_FnTable.GetOverlayTransformTrackedDeviceComponent_callback GetOverlayTransformTrackedDeviceComponent;
+	/** C type : ShowOverlay_callback* */
+	public VR_IVROverlay_FnTable.ShowOverlay_callback ShowOverlay;
+	/** C type : HideOverlay_callback* */
+	public VR_IVROverlay_FnTable.HideOverlay_callback HideOverlay;
+	/** C type : IsOverlayVisible_callback* */
+	public VR_IVROverlay_FnTable.IsOverlayVisible_callback IsOverlayVisible;
+	/** C type : GetTransformForOverlayCoordinates_callback* */
+	public VR_IVROverlay_FnTable.GetTransformForOverlayCoordinates_callback GetTransformForOverlayCoordinates;
+	/** C type : PollNextOverlayEvent_callback* */
+	public VR_IVROverlay_FnTable.PollNextOverlayEvent_callback PollNextOverlayEvent;
+	/** C type : GetOverlayInputMethod_callback* */
+	public VR_IVROverlay_FnTable.GetOverlayInputMethod_callback GetOverlayInputMethod;
+	/** C type : SetOverlayInputMethod_callback* */
+	public VR_IVROverlay_FnTable.SetOverlayInputMethod_callback SetOverlayInputMethod;
+	/** C type : GetOverlayMouseScale_callback* */
+	public VR_IVROverlay_FnTable.GetOverlayMouseScale_callback GetOverlayMouseScale;
+	/** C type : SetOverlayMouseScale_callback* */
+	public VR_IVROverlay_FnTable.SetOverlayMouseScale_callback SetOverlayMouseScale;
+	/** C type : ComputeOverlayIntersection_callback* */
+	public VR_IVROverlay_FnTable.ComputeOverlayIntersection_callback ComputeOverlayIntersection;
+	/** C type : HandleControllerOverlayInteractionAsMouse_callback* */
+	public VR_IVROverlay_FnTable.HandleControllerOverlayInteractionAsMouse_callback HandleControllerOverlayInteractionAsMouse;
+	/** C type : IsHoverTargetOverlay_callback* */
+	public VR_IVROverlay_FnTable.IsHoverTargetOverlay_callback IsHoverTargetOverlay;
+	/** C type : GetGamepadFocusOverlay_callback* */
+	public VR_IVROverlay_FnTable.GetGamepadFocusOverlay_callback GetGamepadFocusOverlay;
+	/** C type : SetGamepadFocusOverlay_callback* */
+	public VR_IVROverlay_FnTable.SetGamepadFocusOverlay_callback SetGamepadFocusOverlay;
+	/** C type : SetOverlayNeighbor_callback* */
+	public VR_IVROverlay_FnTable.SetOverlayNeighbor_callback SetOverlayNeighbor;
+	/** C type : MoveGamepadFocusToNeighbor_callback* */
+	public VR_IVROverlay_FnTable.MoveGamepadFocusToNeighbor_callback MoveGamepadFocusToNeighbor;
+	/** C type : SetOverlayTexture_callback* */
+	public VR_IVROverlay_FnTable.SetOverlayTexture_callback SetOverlayTexture;
+	/** C type : ClearOverlayTexture_callback* */
+	public VR_IVROverlay_FnTable.ClearOverlayTexture_callback ClearOverlayTexture;
+	/** C type : SetOverlayRaw_callback* */
+	public VR_IVROverlay_FnTable.SetOverlayRaw_callback SetOverlayRaw;
+	/** C type : SetOverlayFromFile_callback* */
+	public VR_IVROverlay_FnTable.SetOverlayFromFile_callback SetOverlayFromFile;
+	/** C type : GetOverlayTexture_callback* */
+	public VR_IVROverlay_FnTable.GetOverlayTexture_callback GetOverlayTexture;
+	/** C type : ReleaseNativeOverlayHandle_callback* */
+	public VR_IVROverlay_FnTable.ReleaseNativeOverlayHandle_callback ReleaseNativeOverlayHandle;
+	/** C type : GetOverlayTextureSize_callback* */
+	public VR_IVROverlay_FnTable.GetOverlayTextureSize_callback GetOverlayTextureSize;
+	/** C type : CreateDashboardOverlay_callback* */
+	public VR_IVROverlay_FnTable.CreateDashboardOverlay_callback CreateDashboardOverlay;
+	/** C type : IsDashboardVisible_callback* */
+	public VR_IVROverlay_FnTable.IsDashboardVisible_callback IsDashboardVisible;
+	/** C type : IsActiveDashboardOverlay_callback* */
+	public VR_IVROverlay_FnTable.IsActiveDashboardOverlay_callback IsActiveDashboardOverlay;
+	/** C type : SetDashboardOverlaySceneProcess_callback* */
+	public VR_IVROverlay_FnTable.SetDashboardOverlaySceneProcess_callback SetDashboardOverlaySceneProcess;
+	/** C type : GetDashboardOverlaySceneProcess_callback* */
+	public VR_IVROverlay_FnTable.GetDashboardOverlaySceneProcess_callback GetDashboardOverlaySceneProcess;
+	/** C type : ShowDashboard_callback* */
+	public VR_IVROverlay_FnTable.ShowDashboard_callback ShowDashboard;
+	/** C type : GetPrimaryDashboardDevice_callback* */
+	public VR_IVROverlay_FnTable.GetPrimaryDashboardDevice_callback GetPrimaryDashboardDevice;
+	/** C type : ShowKeyboard_callback* */
+	public VR_IVROverlay_FnTable.ShowKeyboard_callback ShowKeyboard;
+	/** C type : ShowKeyboardForOverlay_callback* */
+	public VR_IVROverlay_FnTable.ShowKeyboardForOverlay_callback ShowKeyboardForOverlay;
+	/** C type : GetKeyboardText_callback* */
+	public VR_IVROverlay_FnTable.GetKeyboardText_callback GetKeyboardText;
+	/** C type : HideKeyboard_callback* */
+	public VR_IVROverlay_FnTable.HideKeyboard_callback HideKeyboard;
+	/** C type : SetKeyboardTransformAbsolute_callback* */
+	public VR_IVROverlay_FnTable.SetKeyboardTransformAbsolute_callback SetKeyboardTransformAbsolute;
+	/** C type : SetKeyboardPositionForOverlay_callback* */
+	public VR_IVROverlay_FnTable.SetKeyboardPositionForOverlay_callback SetKeyboardPositionForOverlay;
+	/** C type : SetOverlayIntersectionMask_callback* */
+	public VR_IVROverlay_FnTable.SetOverlayIntersectionMask_callback SetOverlayIntersectionMask;
+	/** C type : GetOverlayFlags_callback* */
+	public VR_IVROverlay_FnTable.GetOverlayFlags_callback GetOverlayFlags;
+	/** C type : ShowMessageOverlay_callback* */
+	public VR_IVROverlay_FnTable.ShowMessageOverlay_callback ShowMessageOverlay;
+	/** <i>native declaration : headers\openvr_capi.h:1704</i> */
+	public interface FindOverlay_callback extends Callback {
+		int apply(Pointer pchOverlayKey, LongByReference pOverlayHandle);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1705</i> */
+	public interface CreateOverlay_callback extends Callback {
+		int apply(Pointer pchOverlayKey, Pointer pchOverlayFriendlyName, LongByReference pOverlayHandle);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1706</i> */
+	public interface DestroyOverlay_callback extends Callback {
+		int apply(long ulOverlayHandle);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1707</i> */
+	public interface SetHighQualityOverlay_callback extends Callback {
+		int apply(long ulOverlayHandle);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1708</i> */
+	public interface GetHighQualityOverlay_callback extends Callback {
+		long apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1709</i> */
+	public interface GetOverlayKey_callback extends Callback {
+		int apply(long ulOverlayHandle, Pointer pchValue, int unBufferSize, IntByReference pError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1710</i> */
+	public interface GetOverlayName_callback extends Callback {
+		int apply(long ulOverlayHandle, Pointer pchValue, int unBufferSize, IntByReference pError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1711</i> */
+	public interface GetOverlayImageData_callback extends Callback {
+		int apply(long ulOverlayHandle, Pointer pvBuffer, int unBufferSize, IntByReference punWidth, IntByReference punHeight);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1712</i> */
+	public interface GetOverlayErrorNameFromEnum_callback extends Callback {
+		Pointer apply(int error);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1713</i> */
+	public interface SetOverlayRenderingPid_callback extends Callback {
+		int apply(long ulOverlayHandle, int unPID);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1714</i> */
+	public interface GetOverlayRenderingPid_callback extends Callback {
+		int apply(long ulOverlayHandle);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1715</i> */
+	public interface SetOverlayFlag_callback extends Callback {
+		int apply(long ulOverlayHandle, int eOverlayFlag, byte bEnabled);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1716</i> */
+	public interface GetOverlayFlag_callback extends Callback {
+		int apply(long ulOverlayHandle, int eOverlayFlag, Pointer pbEnabled);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1717</i> */
+	public interface SetOverlayColor_callback extends Callback {
+		int apply(long ulOverlayHandle, float fRed, float fGreen, float fBlue);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1718</i> */
+	public interface GetOverlayColor_callback extends Callback {
+		int apply(long ulOverlayHandle, FloatByReference pfRed, FloatByReference pfGreen, FloatByReference pfBlue);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1719</i> */
+	public interface SetOverlayAlpha_callback extends Callback {
+		int apply(long ulOverlayHandle, float fAlpha);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1720</i> */
+	public interface GetOverlayAlpha_callback extends Callback {
+		int apply(long ulOverlayHandle, FloatByReference pfAlpha);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1721</i> */
+	public interface SetOverlayTexelAspect_callback extends Callback {
+		int apply(long ulOverlayHandle, float fTexelAspect);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1722</i> */
+	public interface GetOverlayTexelAspect_callback extends Callback {
+		int apply(long ulOverlayHandle, FloatByReference pfTexelAspect);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1723</i> */
+	public interface SetOverlaySortOrder_callback extends Callback {
+		int apply(long ulOverlayHandle, int unSortOrder);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1724</i> */
+	public interface GetOverlaySortOrder_callback extends Callback {
+		int apply(long ulOverlayHandle, IntByReference punSortOrder);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1725</i> */
+	public interface SetOverlayWidthInMeters_callback extends Callback {
+		int apply(long ulOverlayHandle, float fWidthInMeters);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1726</i> */
+	public interface GetOverlayWidthInMeters_callback extends Callback {
+		int apply(long ulOverlayHandle, FloatByReference pfWidthInMeters);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1727</i> */
+	public interface SetOverlayAutoCurveDistanceRangeInMeters_callback extends Callback {
+		int apply(long ulOverlayHandle, float fMinDistanceInMeters, float fMaxDistanceInMeters);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1728</i> */
+	public interface GetOverlayAutoCurveDistanceRangeInMeters_callback extends Callback {
+		int apply(long ulOverlayHandle, FloatByReference pfMinDistanceInMeters, FloatByReference pfMaxDistanceInMeters);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1729</i> */
+	public interface SetOverlayTextureColorSpace_callback extends Callback {
+		int apply(long ulOverlayHandle, int eTextureColorSpace);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1730</i> */
+	public interface GetOverlayTextureColorSpace_callback extends Callback {
+		int apply(long ulOverlayHandle, IntByReference peTextureColorSpace);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1731</i> */
+	public interface SetOverlayTextureBounds_callback extends Callback {
+		int apply(long ulOverlayHandle, VRTextureBounds_t pOverlayTextureBounds);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1732</i> */
+	public interface GetOverlayTextureBounds_callback extends Callback {
+		int apply(long ulOverlayHandle, VRTextureBounds_t pOverlayTextureBounds);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1733</i> */
+	public interface GetOverlayTransformType_callback extends Callback {
+		int apply(long ulOverlayHandle, IntByReference peTransformType);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1734</i> */
+	public interface SetOverlayTransformAbsolute_callback extends Callback {
+		int apply(long ulOverlayHandle, int eTrackingOrigin, HmdMatrix34_t pmatTrackingOriginToOverlayTransform);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1735</i> */
+	public interface GetOverlayTransformAbsolute_callback extends Callback {
+		int apply(long ulOverlayHandle, IntByReference peTrackingOrigin, HmdMatrix34_t pmatTrackingOriginToOverlayTransform);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1736</i> */
+	public interface SetOverlayTransformTrackedDeviceRelative_callback extends Callback {
+		int apply(long ulOverlayHandle, int unTrackedDevice, HmdMatrix34_t pmatTrackedDeviceToOverlayTransform);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1737</i> */
+	public interface GetOverlayTransformTrackedDeviceRelative_callback extends Callback {
+		int apply(long ulOverlayHandle, IntByReference punTrackedDevice, HmdMatrix34_t pmatTrackedDeviceToOverlayTransform);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1738</i> */
+	public interface SetOverlayTransformTrackedDeviceComponent_callback extends Callback {
+		int apply(long ulOverlayHandle, int unDeviceIndex, Pointer pchComponentName);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1739</i> */
+	public interface GetOverlayTransformTrackedDeviceComponent_callback extends Callback {
+		int apply(long ulOverlayHandle, IntByReference punDeviceIndex, Pointer pchComponentName, int unComponentNameSize);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1740</i> */
+	public interface ShowOverlay_callback extends Callback {
+		int apply(long ulOverlayHandle);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1741</i> */
+	public interface HideOverlay_callback extends Callback {
+		int apply(long ulOverlayHandle);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1742</i> */
+	public interface IsOverlayVisible_callback extends Callback {
+		byte apply(long ulOverlayHandle);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1743</i> */
+	public interface GetTransformForOverlayCoordinates_callback extends Callback {
+		int apply(long ulOverlayHandle, int eTrackingOrigin, HmdVector2_t.ByValue coordinatesInOverlay, HmdMatrix34_t pmatTransform);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1744</i> */
+	public interface PollNextOverlayEvent_callback extends Callback {
+		byte apply(long ulOverlayHandle, VREvent_t pEvent, int uncbVREvent);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1745</i> */
+	public interface GetOverlayInputMethod_callback extends Callback {
+		int apply(long ulOverlayHandle, IntByReference peInputMethod);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1746</i> */
+	public interface SetOverlayInputMethod_callback extends Callback {
+		int apply(long ulOverlayHandle, int eInputMethod);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1747</i> */
+	public interface GetOverlayMouseScale_callback extends Callback {
+		int apply(long ulOverlayHandle, HmdVector2_t pvecMouseScale);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1748</i> */
+	public interface SetOverlayMouseScale_callback extends Callback {
+		int apply(long ulOverlayHandle, HmdVector2_t pvecMouseScale);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1749</i> */
+	public interface ComputeOverlayIntersection_callback extends Callback {
+		byte apply(long ulOverlayHandle, VROverlayIntersectionParams_t pParams, VROverlayIntersectionResults_t pResults);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1750</i> */
+	public interface HandleControllerOverlayInteractionAsMouse_callback extends Callback {
+		byte apply(long ulOverlayHandle, int unControllerDeviceIndex);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1751</i> */
+	public interface IsHoverTargetOverlay_callback extends Callback {
+		byte apply(long ulOverlayHandle);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1752</i> */
+	public interface GetGamepadFocusOverlay_callback extends Callback {
+		long apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1753</i> */
+	public interface SetGamepadFocusOverlay_callback extends Callback {
+		int apply(long ulNewFocusOverlay);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1754</i> */
+	public interface SetOverlayNeighbor_callback extends Callback {
+		int apply(int eDirection, long ulFrom, long ulTo);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1755</i> */
+	public interface MoveGamepadFocusToNeighbor_callback extends Callback {
+		int apply(int eDirection, long ulFrom);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1756</i> */
+	public interface SetOverlayTexture_callback extends Callback {
+		int apply(long ulOverlayHandle, Texture_t pTexture);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1757</i> */
+	public interface ClearOverlayTexture_callback extends Callback {
+		int apply(long ulOverlayHandle);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1758</i> */
+	public interface SetOverlayRaw_callback extends Callback {
+		int apply(long ulOverlayHandle, Pointer pvBuffer, int unWidth, int unHeight, int unDepth);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1759</i> */
+	public interface SetOverlayFromFile_callback extends Callback {
+		int apply(long ulOverlayHandle, Pointer pchFilePath);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1760</i> */
+	public interface GetOverlayTexture_callback extends Callback {
+		int apply(long ulOverlayHandle, PointerByReference pNativeTextureHandle, Pointer pNativeTextureRef, IntByReference pWidth, IntByReference pHeight, IntByReference pNativeFormat, IntByReference pAPIType, IntByReference pColorSpace, VRTextureBounds_t pTextureBounds);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1761</i> */
+	public interface ReleaseNativeOverlayHandle_callback extends Callback {
+		int apply(long ulOverlayHandle, Pointer pNativeTextureHandle);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1762</i> */
+	public interface GetOverlayTextureSize_callback extends Callback {
+		int apply(long ulOverlayHandle, IntByReference pWidth, IntByReference pHeight);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1763</i> */
+	public interface CreateDashboardOverlay_callback extends Callback {
+		int apply(Pointer pchOverlayKey, Pointer pchOverlayFriendlyName, LongByReference pMainHandle, LongByReference pThumbnailHandle);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1764</i> */
+	public interface IsDashboardVisible_callback extends Callback {
+		byte apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1765</i> */
+	public interface IsActiveDashboardOverlay_callback extends Callback {
+		byte apply(long ulOverlayHandle);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1766</i> */
+	public interface SetDashboardOverlaySceneProcess_callback extends Callback {
+		int apply(long ulOverlayHandle, int unProcessId);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1767</i> */
+	public interface GetDashboardOverlaySceneProcess_callback extends Callback {
+		int apply(long ulOverlayHandle, IntByReference punProcessId);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1768</i> */
+	public interface ShowDashboard_callback extends Callback {
+		void apply(Pointer pchOverlayToShow);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1769</i> */
+	public interface GetPrimaryDashboardDevice_callback extends Callback {
+		int apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1770</i> */
+	public interface ShowKeyboard_callback extends Callback {
+		int apply(int eInputMode, int eLineInputMode, Pointer pchDescription, int unCharMax, Pointer pchExistingText, byte bUseMinimalMode, long uUserValue);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1771</i> */
+	public interface ShowKeyboardForOverlay_callback extends Callback {
+		int apply(long ulOverlayHandle, int eInputMode, int eLineInputMode, Pointer pchDescription, int unCharMax, Pointer pchExistingText, byte bUseMinimalMode, long uUserValue);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1772</i> */
+	public interface GetKeyboardText_callback extends Callback {
+		int apply(Pointer pchText, int cchText);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1773</i> */
+	public interface HideKeyboard_callback extends Callback {
+		void apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1774</i> */
+	public interface SetKeyboardTransformAbsolute_callback extends Callback {
+		void apply(int eTrackingOrigin, HmdMatrix34_t pmatTrackingOriginToKeyboardTransform);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1775</i> */
+	public interface SetKeyboardPositionForOverlay_callback extends Callback {
+		void apply(long ulOverlayHandle, com.jme3.system.jopenvr.HmdRect2_t.ByValue avoidRect);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1776</i> */
+	public interface SetOverlayIntersectionMask_callback extends Callback {
+		int apply(long ulOverlayHandle, VROverlayIntersectionMaskPrimitive_t pMaskPrimitives, int unNumMaskPrimitives, int unPrimitiveSize);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1777</i> */
+	public interface GetOverlayFlags_callback extends Callback {
+		int apply(long ulOverlayHandle, IntByReference pFlags);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1778</i> */
+	public interface ShowMessageOverlay_callback extends Callback {
+		int apply(Pointer pchText, Pointer pchCaption, Pointer pchButton0Text, Pointer pchButton1Text, Pointer pchButton2Text, Pointer pchButton3Text);
+	};
+	public VR_IVROverlay_FnTable() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("FindOverlay", "CreateOverlay", "DestroyOverlay", "SetHighQualityOverlay", "GetHighQualityOverlay", "GetOverlayKey", "GetOverlayName", "GetOverlayImageData", "GetOverlayErrorNameFromEnum", "SetOverlayRenderingPid", "GetOverlayRenderingPid", "SetOverlayFlag", "GetOverlayFlag", "SetOverlayColor", "GetOverlayColor", "SetOverlayAlpha", "GetOverlayAlpha", "SetOverlayTexelAspect", "GetOverlayTexelAspect", "SetOverlaySortOrder", "GetOverlaySortOrder", "SetOverlayWidthInMeters", "GetOverlayWidthInMeters", "SetOverlayAutoCurveDistanceRangeInMeters", "GetOverlayAutoCurveDistanceRangeInMeters", "SetOverlayTextureColorSpace", "GetOverlayTextureColorSpace", "SetOverlayTextureBounds", "GetOverlayTextureBounds", "GetOverlayTransformType", "SetOverlayTransformAbsolute", "GetOverlayTransformAbsolute", "SetOverlayTransformTrackedDeviceRelative", "GetOverlayTransformTrackedDeviceRelative", "SetOverlayTransformTrackedDeviceComponent", "GetOverlayTransformTrackedDeviceComponent", "ShowOverlay", "HideOverlay", "IsOverlayVisible", "GetTransformForOverlayCoordinates", "PollNextOverlayEvent", "GetOverlayInputMethod", "SetOverlayInputMethod", "GetOverlayMouseScale", "SetOverlayMouseScale", "ComputeOverlayIntersection", "HandleControllerOverlayInteractionAsMouse", "IsHoverTargetOverlay", "GetGamepadFocusOverlay", "SetGamepadFocusOverlay", "SetOverlayNeighbor", "MoveGamepadFocusToNeighbor", "SetOverlayTexture", "ClearOverlayTexture", "SetOverlayRaw", "SetOverlayFromFile", "GetOverlayTexture", "ReleaseNativeOverlayHandle", "GetOverlayTextureSize", "CreateDashboardOverlay", "IsDashboardVisible", "IsActiveDashboardOverlay", "SetDashboardOverlaySceneProcess", "GetDashboardOverlaySceneProcess", "ShowDashboard", "GetPrimaryDashboardDevice", "ShowKeyboard", "ShowKeyboardForOverlay", "GetKeyboardText", "HideKeyboard", "SetKeyboardTransformAbsolute", "SetKeyboardPositionForOverlay", "SetOverlayIntersectionMask", "GetOverlayFlags", "ShowMessageOverlay");
+	}
+	public VR_IVROverlay_FnTable(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VR_IVROverlay_FnTable implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VR_IVROverlay_FnTable implements Structure.ByValue {
+		
+	};
+}

+ 139 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VR_IVRRenderModels_FnTable.java

@@ -0,0 +1,139 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Callback;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import com.sun.jna.ptr.IntByReference;
+import com.sun.jna.ptr.PointerByReference;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1817</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VR_IVRRenderModels_FnTable extends Structure {
+	/** C type : LoadRenderModel_Async_callback* */
+	public VR_IVRRenderModels_FnTable.LoadRenderModel_Async_callback LoadRenderModel_Async;
+	/** C type : FreeRenderModel_callback* */
+	public VR_IVRRenderModels_FnTable.FreeRenderModel_callback FreeRenderModel;
+	/** C type : LoadTexture_Async_callback* */
+	public VR_IVRRenderModels_FnTable.LoadTexture_Async_callback LoadTexture_Async;
+	/** C type : FreeTexture_callback* */
+	public VR_IVRRenderModels_FnTable.FreeTexture_callback FreeTexture;
+	/** C type : LoadTextureD3D11_Async_callback* */
+	public VR_IVRRenderModels_FnTable.LoadTextureD3D11_Async_callback LoadTextureD3D11_Async;
+	/** C type : LoadIntoTextureD3D11_Async_callback* */
+	public VR_IVRRenderModels_FnTable.LoadIntoTextureD3D11_Async_callback LoadIntoTextureD3D11_Async;
+	/** C type : FreeTextureD3D11_callback* */
+	public VR_IVRRenderModels_FnTable.FreeTextureD3D11_callback FreeTextureD3D11;
+	/** C type : GetRenderModelName_callback* */
+	public VR_IVRRenderModels_FnTable.GetRenderModelName_callback GetRenderModelName;
+	/** C type : GetRenderModelCount_callback* */
+	public VR_IVRRenderModels_FnTable.GetRenderModelCount_callback GetRenderModelCount;
+	/** C type : GetComponentCount_callback* */
+	public VR_IVRRenderModels_FnTable.GetComponentCount_callback GetComponentCount;
+	/** C type : GetComponentName_callback* */
+	public VR_IVRRenderModels_FnTable.GetComponentName_callback GetComponentName;
+	/** C type : GetComponentButtonMask_callback* */
+	public VR_IVRRenderModels_FnTable.GetComponentButtonMask_callback GetComponentButtonMask;
+	/** C type : GetComponentRenderModelName_callback* */
+	public VR_IVRRenderModels_FnTable.GetComponentRenderModelName_callback GetComponentRenderModelName;
+	/** C type : GetComponentState_callback* */
+	public VR_IVRRenderModels_FnTable.GetComponentState_callback GetComponentState;
+	/** C type : RenderModelHasComponent_callback* */
+	public VR_IVRRenderModels_FnTable.RenderModelHasComponent_callback RenderModelHasComponent;
+	/** C type : GetRenderModelThumbnailURL_callback* */
+	public VR_IVRRenderModels_FnTable.GetRenderModelThumbnailURL_callback GetRenderModelThumbnailURL;
+	/** C type : GetRenderModelOriginalPath_callback* */
+	public VR_IVRRenderModels_FnTable.GetRenderModelOriginalPath_callback GetRenderModelOriginalPath;
+	/** C type : GetRenderModelErrorNameFromEnum_callback* */
+	public VR_IVRRenderModels_FnTable.GetRenderModelErrorNameFromEnum_callback GetRenderModelErrorNameFromEnum;
+	/** <i>native declaration : headers\openvr_capi.h:1799</i> */
+	public interface LoadRenderModel_Async_callback extends Callback {
+		int apply(Pointer pchRenderModelName, PointerByReference ppRenderModel);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1800</i> */
+	public interface FreeRenderModel_callback extends Callback {
+		void apply(RenderModel_t pRenderModel);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1801</i> */
+	public interface LoadTexture_Async_callback extends Callback {
+		int apply(int textureId, PointerByReference ppTexture);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1802</i> */
+	public interface FreeTexture_callback extends Callback {
+		void apply(RenderModel_TextureMap_t pTexture);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1803</i> */
+	public interface LoadTextureD3D11_Async_callback extends Callback {
+		int apply(int textureId, Pointer pD3D11Device, PointerByReference ppD3D11Texture2D);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1804</i> */
+	public interface LoadIntoTextureD3D11_Async_callback extends Callback {
+		int apply(int textureId, Pointer pDstTexture);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1805</i> */
+	public interface FreeTextureD3D11_callback extends Callback {
+		void apply(Pointer pD3D11Texture2D);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1806</i> */
+	public interface GetRenderModelName_callback extends Callback {
+		int apply(int unRenderModelIndex, Pointer pchRenderModelName, int unRenderModelNameLen);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1807</i> */
+	public interface GetRenderModelCount_callback extends Callback {
+		int apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1808</i> */
+	public interface GetComponentCount_callback extends Callback {
+		int apply(Pointer pchRenderModelName);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1809</i> */
+	public interface GetComponentName_callback extends Callback {
+		int apply(Pointer pchRenderModelName, int unComponentIndex, Pointer pchComponentName, int unComponentNameLen);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1810</i> */
+	public interface GetComponentButtonMask_callback extends Callback {
+		long apply(Pointer pchRenderModelName, Pointer pchComponentName);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1811</i> */
+	public interface GetComponentRenderModelName_callback extends Callback {
+		int apply(Pointer pchRenderModelName, Pointer pchComponentName, Pointer pchComponentRenderModelName, int unComponentRenderModelNameLen);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1812</i> */
+	public interface GetComponentState_callback extends Callback {
+		byte apply(Pointer pchRenderModelName, Pointer pchComponentName, VRControllerState_t pControllerState, RenderModel_ControllerMode_State_t pState, RenderModel_ComponentState_t pComponentState);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1813</i> */
+	public interface RenderModelHasComponent_callback extends Callback {
+		byte apply(Pointer pchRenderModelName, Pointer pchComponentName);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1814</i> */
+	public interface GetRenderModelThumbnailURL_callback extends Callback {
+		int apply(Pointer pchRenderModelName, Pointer pchThumbnailURL, int unThumbnailURLLen, IntByReference peError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1815</i> */
+	public interface GetRenderModelOriginalPath_callback extends Callback {
+		int apply(Pointer pchRenderModelName, Pointer pchOriginalPath, int unOriginalPathLen, IntByReference peError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1816</i> */
+	public interface GetRenderModelErrorNameFromEnum_callback extends Callback {
+		Pointer apply(int error);
+	};
+	public VR_IVRRenderModels_FnTable() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("LoadRenderModel_Async", "FreeRenderModel", "LoadTexture_Async", "FreeTexture", "LoadTextureD3D11_Async", "LoadIntoTextureD3D11_Async", "FreeTextureD3D11", "GetRenderModelName", "GetRenderModelCount", "GetComponentCount", "GetComponentName", "GetComponentButtonMask", "GetComponentRenderModelName", "GetComponentState", "RenderModelHasComponent", "GetRenderModelThumbnailURL", "GetRenderModelOriginalPath", "GetRenderModelErrorNameFromEnum");
+	}
+	public VR_IVRRenderModels_FnTable(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VR_IVRRenderModels_FnTable implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VR_IVRRenderModels_FnTable implements Structure.ByValue {
+		
+	};
+}

+ 50 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VR_IVRResources_FnTable.java

@@ -0,0 +1,50 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Callback;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1871</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VR_IVRResources_FnTable extends Structure {
+	/** C type : LoadSharedResource_callback* */
+	public VR_IVRResources_FnTable.LoadSharedResource_callback LoadSharedResource;
+	/** C type : GetResourceFullPath_callback* */
+	public VR_IVRResources_FnTable.GetResourceFullPath_callback GetResourceFullPath;
+	/** <i>native declaration : headers\openvr_capi.h:1869</i> */
+	public interface LoadSharedResource_callback extends Callback {
+		int apply(Pointer pchResourceName, Pointer pchBuffer, int unBufferLen);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1870</i> */
+	public interface GetResourceFullPath_callback extends Callback {
+		int apply(Pointer pchResourceName, Pointer pchResourceTypeDirectory, Pointer pchPathBuffer, int unBufferLen);
+	};
+	public VR_IVRResources_FnTable() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("LoadSharedResource", "GetResourceFullPath");
+	}
+	/**
+	 * @param LoadSharedResource C type : LoadSharedResource_callback*<br>
+	 * @param GetResourceFullPath C type : GetResourceFullPath_callback*
+	 */
+	public VR_IVRResources_FnTable(VR_IVRResources_FnTable.LoadSharedResource_callback LoadSharedResource, VR_IVRResources_FnTable.GetResourceFullPath_callback GetResourceFullPath) {
+		super();
+		this.LoadSharedResource = LoadSharedResource;
+		this.GetResourceFullPath = GetResourceFullPath;
+	}
+	public VR_IVRResources_FnTable(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VR_IVRResources_FnTable implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VR_IVRResources_FnTable implements Structure.ByValue {
+		
+	};
+}

+ 91 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VR_IVRScreenshots_FnTable.java

@@ -0,0 +1,91 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Callback;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import com.sun.jna.ptr.IntByReference;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1865</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VR_IVRScreenshots_FnTable extends Structure {
+	/** C type : RequestScreenshot_callback* */
+	public VR_IVRScreenshots_FnTable.RequestScreenshot_callback RequestScreenshot;
+	/** C type : HookScreenshot_callback* */
+	public VR_IVRScreenshots_FnTable.HookScreenshot_callback HookScreenshot;
+	/** C type : GetScreenshotPropertyType_callback* */
+	public VR_IVRScreenshots_FnTable.GetScreenshotPropertyType_callback GetScreenshotPropertyType;
+	/** C type : GetScreenshotPropertyFilename_callback* */
+	public VR_IVRScreenshots_FnTable.GetScreenshotPropertyFilename_callback GetScreenshotPropertyFilename;
+	/** C type : UpdateScreenshotProgress_callback* */
+	public VR_IVRScreenshots_FnTable.UpdateScreenshotProgress_callback UpdateScreenshotProgress;
+	/** C type : TakeStereoScreenshot_callback* */
+	public VR_IVRScreenshots_FnTable.TakeStereoScreenshot_callback TakeStereoScreenshot;
+	/** C type : SubmitScreenshot_callback* */
+	public VR_IVRScreenshots_FnTable.SubmitScreenshot_callback SubmitScreenshot;
+	/** <i>native declaration : headers\openvr_capi.h:1858</i> */
+	public interface RequestScreenshot_callback extends Callback {
+		int apply(IntByReference pOutScreenshotHandle, int type, Pointer pchPreviewFilename, Pointer pchVRFilename);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1859</i> */
+	public interface HookScreenshot_callback extends Callback {
+		int apply(IntByReference pSupportedTypes, int numTypes);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1860</i> */
+	public interface GetScreenshotPropertyType_callback extends Callback {
+		int apply(int screenshotHandle, IntByReference pError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1861</i> */
+	public interface GetScreenshotPropertyFilename_callback extends Callback {
+		int apply(int screenshotHandle, int filenameType, Pointer pchFilename, int cchFilename, IntByReference pError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1862</i> */
+	public interface UpdateScreenshotProgress_callback extends Callback {
+		int apply(int screenshotHandle, float flProgress);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1863</i> */
+	public interface TakeStereoScreenshot_callback extends Callback {
+		int apply(IntByReference pOutScreenshotHandle, Pointer pchPreviewFilename, Pointer pchVRFilename);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1864</i> */
+	public interface SubmitScreenshot_callback extends Callback {
+		int apply(int screenshotHandle, int type, Pointer pchSourcePreviewFilename, Pointer pchSourceVRFilename);
+	};
+	public VR_IVRScreenshots_FnTable() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("RequestScreenshot", "HookScreenshot", "GetScreenshotPropertyType", "GetScreenshotPropertyFilename", "UpdateScreenshotProgress", "TakeStereoScreenshot", "SubmitScreenshot");
+	}
+	/**
+	 * @param RequestScreenshot C type : RequestScreenshot_callback*<br>
+	 * @param HookScreenshot C type : HookScreenshot_callback*<br>
+	 * @param GetScreenshotPropertyType C type : GetScreenshotPropertyType_callback*<br>
+	 * @param GetScreenshotPropertyFilename C type : GetScreenshotPropertyFilename_callback*<br>
+	 * @param UpdateScreenshotProgress C type : UpdateScreenshotProgress_callback*<br>
+	 * @param TakeStereoScreenshot C type : TakeStereoScreenshot_callback*<br>
+	 * @param SubmitScreenshot C type : SubmitScreenshot_callback*
+	 */
+	public VR_IVRScreenshots_FnTable(VR_IVRScreenshots_FnTable.RequestScreenshot_callback RequestScreenshot, VR_IVRScreenshots_FnTable.HookScreenshot_callback HookScreenshot, VR_IVRScreenshots_FnTable.GetScreenshotPropertyType_callback GetScreenshotPropertyType, VR_IVRScreenshots_FnTable.GetScreenshotPropertyFilename_callback GetScreenshotPropertyFilename, VR_IVRScreenshots_FnTable.UpdateScreenshotProgress_callback UpdateScreenshotProgress, VR_IVRScreenshots_FnTable.TakeStereoScreenshot_callback TakeStereoScreenshot, VR_IVRScreenshots_FnTable.SubmitScreenshot_callback SubmitScreenshot) {
+		super();
+		this.RequestScreenshot = RequestScreenshot;
+		this.HookScreenshot = HookScreenshot;
+		this.GetScreenshotPropertyType = GetScreenshotPropertyType;
+		this.GetScreenshotPropertyFilename = GetScreenshotPropertyFilename;
+		this.UpdateScreenshotProgress = UpdateScreenshotProgress;
+		this.TakeStereoScreenshot = TakeStereoScreenshot;
+		this.SubmitScreenshot = SubmitScreenshot;
+	}
+	public VR_IVRScreenshots_FnTable(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VR_IVRScreenshots_FnTable implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VR_IVRScreenshots_FnTable implements Structure.ByValue {
+		
+	};
+}

+ 102 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VR_IVRSettings_FnTable.java

@@ -0,0 +1,102 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Callback;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import com.sun.jna.ptr.IntByReference;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * <i>native declaration : headers\openvr_capi.h:1849</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VR_IVRSettings_FnTable extends Structure {
+	/** C type : GetSettingsErrorNameFromEnum_callback* */
+	public VR_IVRSettings_FnTable.GetSettingsErrorNameFromEnum_callback GetSettingsErrorNameFromEnum;
+	/** C type : Sync_callback* */
+	public VR_IVRSettings_FnTable.Sync_callback Sync;
+	/** C type : SetBool_callback* */
+	public VR_IVRSettings_FnTable.SetBool_callback SetBool;
+	/** C type : SetInt32_callback* */
+	public VR_IVRSettings_FnTable.SetInt32_callback SetInt32;
+	/** C type : SetFloat_callback* */
+	public VR_IVRSettings_FnTable.SetFloat_callback SetFloat;
+	/** C type : SetString_callback* */
+	public VR_IVRSettings_FnTable.SetString_callback SetString;
+	/** C type : GetBool_callback* */
+	public VR_IVRSettings_FnTable.GetBool_callback GetBool;
+	/** C type : GetInt32_callback* */
+	public VR_IVRSettings_FnTable.GetInt32_callback GetInt32;
+	/** C type : GetFloat_callback* */
+	public VR_IVRSettings_FnTable.GetFloat_callback GetFloat;
+	/** C type : GetString_callback* */
+	public VR_IVRSettings_FnTable.GetString_callback GetString;
+	/** C type : RemoveSection_callback* */
+	public VR_IVRSettings_FnTable.RemoveSection_callback RemoveSection;
+	/** C type : RemoveKeyInSection_callback* */
+	public VR_IVRSettings_FnTable.RemoveKeyInSection_callback RemoveKeyInSection;
+	/** <i>native declaration : headers\openvr_capi.h:1837</i> */
+	public interface GetSettingsErrorNameFromEnum_callback extends Callback {
+		Pointer apply(int eError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1838</i> */
+	public interface Sync_callback extends Callback {
+		byte apply(byte bForce, IntByReference peError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1839</i> */
+	public interface SetBool_callback extends Callback {
+		void apply(Pointer pchSection, Pointer pchSettingsKey, byte bValue, IntByReference peError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1840</i> */
+	public interface SetInt32_callback extends Callback {
+		void apply(Pointer pchSection, Pointer pchSettingsKey, int nValue, IntByReference peError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1841</i> */
+	public interface SetFloat_callback extends Callback {
+		void apply(Pointer pchSection, Pointer pchSettingsKey, float flValue, IntByReference peError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1842</i> */
+	public interface SetString_callback extends Callback {
+		void apply(Pointer pchSection, Pointer pchSettingsKey, Pointer pchValue, IntByReference peError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1843</i> */
+	public interface GetBool_callback extends Callback {
+		byte apply(Pointer pchSection, Pointer pchSettingsKey, IntByReference peError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1844</i> */
+	public interface GetInt32_callback extends Callback {
+		int apply(Pointer pchSection, Pointer pchSettingsKey, IntByReference peError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1845</i> */
+	public interface GetFloat_callback extends Callback {
+		float apply(Pointer pchSection, Pointer pchSettingsKey, IntByReference peError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1846</i> */
+	public interface GetString_callback extends Callback {
+		void apply(Pointer pchSection, Pointer pchSettingsKey, Pointer pchValue, int unValueLen, IntByReference peError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1847</i> */
+	public interface RemoveSection_callback extends Callback {
+		void apply(Pointer pchSection, IntByReference peError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1848</i> */
+	public interface RemoveKeyInSection_callback extends Callback {
+		void apply(Pointer pchSection, Pointer pchSettingsKey, IntByReference peError);
+	};
+	public VR_IVRSettings_FnTable() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("GetSettingsErrorNameFromEnum", "Sync", "SetBool", "SetInt32", "SetFloat", "SetString", "GetBool", "GetInt32", "GetFloat", "GetString", "RemoveSection", "RemoveKeyInSection");
+	}
+	public VR_IVRSettings_FnTable(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VR_IVRSettings_FnTable implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VR_IVRSettings_FnTable implements Structure.ByValue {
+		
+	};
+}

+ 297 - 0
jme3-vr/src/main/java/com/jme3/system/jopenvr/VR_IVRSystem_FnTable.java

@@ -0,0 +1,297 @@
+package com.jme3.system.jopenvr;
+import com.sun.jna.Callback;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import com.sun.jna.ptr.FloatByReference;
+import com.sun.jna.ptr.IntByReference;
+import com.sun.jna.ptr.LongByReference;
+import java.util.Arrays;
+import java.util.List;
+/**
+ * OpenVR Function Pointer Tables<br>
+ * <i>native declaration : headers\openvr_capi.h:1385</i><br>
+ * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
+ * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
+ * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
+ */
+public class VR_IVRSystem_FnTable extends Structure {
+	/** C type : GetRecommendedRenderTargetSize_callback* */
+	public VR_IVRSystem_FnTable.GetRecommendedRenderTargetSize_callback GetRecommendedRenderTargetSize;
+	/** C type : GetProjectionMatrix_callback* */
+	public VR_IVRSystem_FnTable.GetProjectionMatrix_callback GetProjectionMatrix;
+	/** C type : GetProjectionRaw_callback* */
+	public VR_IVRSystem_FnTable.GetProjectionRaw_callback GetProjectionRaw;
+	/** C type : ComputeDistortion_callback* */
+	public VR_IVRSystem_FnTable.ComputeDistortion_callback ComputeDistortion;
+	/** C type : GetEyeToHeadTransform_callback* */
+	public VR_IVRSystem_FnTable.GetEyeToHeadTransform_callback GetEyeToHeadTransform;
+	/** C type : GetTimeSinceLastVsync_callback* */
+	public VR_IVRSystem_FnTable.GetTimeSinceLastVsync_callback GetTimeSinceLastVsync;
+	/** C type : GetD3D9AdapterIndex_callback* */
+	public VR_IVRSystem_FnTable.GetD3D9AdapterIndex_callback GetD3D9AdapterIndex;
+	/** C type : GetDXGIOutputInfo_callback* */
+	public com.jme3.system.jopenvr.VR_IVRExtendedDisplay_FnTable.GetDXGIOutputInfo_callback GetDXGIOutputInfo;
+	/** C type : IsDisplayOnDesktop_callback* */
+	public VR_IVRSystem_FnTable.IsDisplayOnDesktop_callback IsDisplayOnDesktop;
+	/** C type : SetDisplayVisibility_callback* */
+	public VR_IVRSystem_FnTable.SetDisplayVisibility_callback SetDisplayVisibility;
+	/** C type : GetDeviceToAbsoluteTrackingPose_callback* */
+	public VR_IVRSystem_FnTable.GetDeviceToAbsoluteTrackingPose_callback GetDeviceToAbsoluteTrackingPose;
+	/** C type : ResetSeatedZeroPose_callback* */
+	public VR_IVRSystem_FnTable.ResetSeatedZeroPose_callback ResetSeatedZeroPose;
+	/** C type : GetSeatedZeroPoseToStandingAbsoluteTrackingPose_callback* */
+	public VR_IVRSystem_FnTable.GetSeatedZeroPoseToStandingAbsoluteTrackingPose_callback GetSeatedZeroPoseToStandingAbsoluteTrackingPose;
+	/** C type : GetRawZeroPoseToStandingAbsoluteTrackingPose_callback* */
+	public VR_IVRSystem_FnTable.GetRawZeroPoseToStandingAbsoluteTrackingPose_callback GetRawZeroPoseToStandingAbsoluteTrackingPose;
+	/** C type : GetSortedTrackedDeviceIndicesOfClass_callback* */
+	public VR_IVRSystem_FnTable.GetSortedTrackedDeviceIndicesOfClass_callback GetSortedTrackedDeviceIndicesOfClass;
+	/** C type : GetTrackedDeviceActivityLevel_callback* */
+	public VR_IVRSystem_FnTable.GetTrackedDeviceActivityLevel_callback GetTrackedDeviceActivityLevel;
+	/** C type : ApplyTransform_callback* */
+	public VR_IVRSystem_FnTable.ApplyTransform_callback ApplyTransform;
+	/** C type : GetTrackedDeviceIndexForControllerRole_callback* */
+	public VR_IVRSystem_FnTable.GetTrackedDeviceIndexForControllerRole_callback GetTrackedDeviceIndexForControllerRole;
+	/** C type : GetControllerRoleForTrackedDeviceIndex_callback* */
+	public VR_IVRSystem_FnTable.GetControllerRoleForTrackedDeviceIndex_callback GetControllerRoleForTrackedDeviceIndex;
+	/** C type : GetTrackedDeviceClass_callback* */
+	public VR_IVRSystem_FnTable.GetTrackedDeviceClass_callback GetTrackedDeviceClass;
+	/** C type : IsTrackedDeviceConnected_callback* */
+	public VR_IVRSystem_FnTable.IsTrackedDeviceConnected_callback IsTrackedDeviceConnected;
+	/** C type : GetBoolTrackedDeviceProperty_callback* */
+	public VR_IVRSystem_FnTable.GetBoolTrackedDeviceProperty_callback GetBoolTrackedDeviceProperty;
+	/** C type : GetFloatTrackedDeviceProperty_callback* */
+	public VR_IVRSystem_FnTable.GetFloatTrackedDeviceProperty_callback GetFloatTrackedDeviceProperty;
+	/** C type : GetInt32TrackedDeviceProperty_callback* */
+	public VR_IVRSystem_FnTable.GetInt32TrackedDeviceProperty_callback GetInt32TrackedDeviceProperty;
+	/** C type : GetUint64TrackedDeviceProperty_callback* */
+	public VR_IVRSystem_FnTable.GetUint64TrackedDeviceProperty_callback GetUint64TrackedDeviceProperty;
+	/** C type : GetMatrix34TrackedDeviceProperty_callback* */
+	public VR_IVRSystem_FnTable.GetMatrix34TrackedDeviceProperty_callback GetMatrix34TrackedDeviceProperty;
+	/** C type : GetStringTrackedDeviceProperty_callback* */
+	public VR_IVRSystem_FnTable.GetStringTrackedDeviceProperty_callback GetStringTrackedDeviceProperty;
+	/** C type : GetPropErrorNameFromEnum_callback* */
+	public VR_IVRSystem_FnTable.GetPropErrorNameFromEnum_callback GetPropErrorNameFromEnum;
+	/** C type : PollNextEvent_callback* */
+	public VR_IVRSystem_FnTable.PollNextEvent_callback PollNextEvent;
+	/** C type : PollNextEventWithPose_callback* */
+	public VR_IVRSystem_FnTable.PollNextEventWithPose_callback PollNextEventWithPose;
+	/** C type : GetEventTypeNameFromEnum_callback* */
+	public VR_IVRSystem_FnTable.GetEventTypeNameFromEnum_callback GetEventTypeNameFromEnum;
+	/** C type : GetHiddenAreaMesh_callback* */
+	public VR_IVRSystem_FnTable.GetHiddenAreaMesh_callback GetHiddenAreaMesh;
+	/** C type : GetControllerState_callback* */
+	public VR_IVRSystem_FnTable.GetControllerState_callback GetControllerState;
+	/** C type : GetControllerStateWithPose_callback* */
+	public VR_IVRSystem_FnTable.GetControllerStateWithPose_callback GetControllerStateWithPose;
+	/** C type : TriggerHapticPulse_callback* */
+	public VR_IVRSystem_FnTable.TriggerHapticPulse_callback TriggerHapticPulse;
+	/** C type : GetButtonIdNameFromEnum_callback* */
+	public VR_IVRSystem_FnTable.GetButtonIdNameFromEnum_callback GetButtonIdNameFromEnum;
+	/** C type : GetControllerAxisTypeNameFromEnum_callback* */
+	public VR_IVRSystem_FnTable.GetControllerAxisTypeNameFromEnum_callback GetControllerAxisTypeNameFromEnum;
+	/** C type : CaptureInputFocus_callback* */
+	public VR_IVRSystem_FnTable.CaptureInputFocus_callback CaptureInputFocus;
+	/** C type : ReleaseInputFocus_callback* */
+	public VR_IVRSystem_FnTable.ReleaseInputFocus_callback ReleaseInputFocus;
+	/** C type : IsInputFocusCapturedByAnotherProcess_callback* */
+	public VR_IVRSystem_FnTable.IsInputFocusCapturedByAnotherProcess_callback IsInputFocusCapturedByAnotherProcess;
+	/** C type : DriverDebugRequest_callback* */
+	public VR_IVRSystem_FnTable.DriverDebugRequest_callback DriverDebugRequest;
+	/** C type : PerformFirmwareUpdate_callback* */
+	public VR_IVRSystem_FnTable.PerformFirmwareUpdate_callback PerformFirmwareUpdate;
+	/** C type : AcknowledgeQuit_Exiting_callback* */
+	public VR_IVRSystem_FnTable.AcknowledgeQuit_Exiting_callback AcknowledgeQuit_Exiting;
+	/** C type : AcknowledgeQuit_UserPrompt_callback* */
+	public VR_IVRSystem_FnTable.AcknowledgeQuit_UserPrompt_callback AcknowledgeQuit_UserPrompt;
+	/** <i>native declaration : headers\openvr_capi.h:1341</i> */
+	public interface GetRecommendedRenderTargetSize_callback extends Callback {
+		void apply(IntByReference pnWidth, IntByReference pnHeight);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1342</i> */
+	public interface GetProjectionMatrix_callback extends Callback {
+		com.jme3.system.jopenvr.HmdMatrix44_t.ByValue apply(int eEye, float fNearZ, float fFarZ);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1343</i> */
+	public interface GetProjectionRaw_callback extends Callback {
+		void apply(int eEye, FloatByReference pfLeft, FloatByReference pfRight, FloatByReference pfTop, FloatByReference pfBottom);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1344</i> */
+	public interface ComputeDistortion_callback extends Callback {
+		byte apply(int eEye, float fU, float fV, DistortionCoordinates_t pDistortionCoordinates);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1345</i> */
+	public interface GetEyeToHeadTransform_callback extends Callback {
+		HmdMatrix34_t.ByValue apply(int eEye);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1346</i> */
+	public interface GetTimeSinceLastVsync_callback extends Callback {
+		byte apply(FloatByReference pfSecondsSinceLastVsync, LongByReference pulFrameCounter);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1347</i> */
+	public interface GetD3D9AdapterIndex_callback extends Callback {
+		int apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1348</i> */
+	public interface GetDXGIOutputInfo_callback extends Callback {
+		void apply(IntByReference pnAdapterIndex);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1349</i> */
+	public interface IsDisplayOnDesktop_callback extends Callback {
+		byte apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1350</i> */
+	public interface SetDisplayVisibility_callback extends Callback {
+		byte apply(byte bIsVisibleOnDesktop);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1351</i> */
+	public interface GetDeviceToAbsoluteTrackingPose_callback extends Callback {
+		void apply(int eOrigin, float fPredictedSecondsToPhotonsFromNow, TrackedDevicePose_t pTrackedDevicePoseArray, int unTrackedDevicePoseArrayCount);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1352</i> */
+	public interface ResetSeatedZeroPose_callback extends Callback {
+		void apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1353</i> */
+	public interface GetSeatedZeroPoseToStandingAbsoluteTrackingPose_callback extends Callback {
+		HmdMatrix34_t.ByValue apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1354</i> */
+	public interface GetRawZeroPoseToStandingAbsoluteTrackingPose_callback extends Callback {
+		HmdMatrix34_t.ByValue apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1355</i> */
+	public interface GetSortedTrackedDeviceIndicesOfClass_callback extends Callback {
+		int apply(int eTrackedDeviceClass, IntByReference punTrackedDeviceIndexArray, int unTrackedDeviceIndexArrayCount, int unRelativeToTrackedDeviceIndex);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1356</i> */
+	public interface GetTrackedDeviceActivityLevel_callback extends Callback {
+		int apply(int unDeviceId);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1357</i> */
+	public interface ApplyTransform_callback extends Callback {
+		void apply(TrackedDevicePose_t pOutputPose, TrackedDevicePose_t pTrackedDevicePose, HmdMatrix34_t pTransform);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1358</i> */
+	public interface GetTrackedDeviceIndexForControllerRole_callback extends Callback {
+		int apply(int unDeviceType);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1359</i> */
+	public interface GetControllerRoleForTrackedDeviceIndex_callback extends Callback {
+		int apply(int unDeviceIndex);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1360</i> */
+	public interface GetTrackedDeviceClass_callback extends Callback {
+		int apply(int unDeviceIndex);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1361</i> */
+	public interface IsTrackedDeviceConnected_callback extends Callback {
+		byte apply(int unDeviceIndex);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1362</i> */
+	public interface GetBoolTrackedDeviceProperty_callback extends Callback {
+		byte apply(int unDeviceIndex, int prop, IntByReference pError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1363</i> */
+	public interface GetFloatTrackedDeviceProperty_callback extends Callback {
+		float apply(int unDeviceIndex, int prop, IntByReference pError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1364</i> */
+	public interface GetInt32TrackedDeviceProperty_callback extends Callback {
+		int apply(int unDeviceIndex, int prop, IntByReference pError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1365</i> */
+	public interface GetUint64TrackedDeviceProperty_callback extends Callback {
+		long apply(int unDeviceIndex, int prop, IntByReference pError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1366</i> */
+	public interface GetMatrix34TrackedDeviceProperty_callback extends Callback {
+		HmdMatrix34_t.ByValue apply(int unDeviceIndex, int prop, IntByReference pError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1367</i> */
+	public interface GetStringTrackedDeviceProperty_callback extends Callback {
+		int apply(int unDeviceIndex, int prop, Pointer pchValue, int unBufferSize, IntByReference pError);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1368</i> */
+	public interface GetPropErrorNameFromEnum_callback extends Callback {
+		Pointer apply(int error);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1369</i> */
+	public interface PollNextEvent_callback extends Callback {
+		byte apply(VREvent_t pEvent, int uncbVREvent);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1370</i> */
+	public interface PollNextEventWithPose_callback extends Callback {
+		byte apply(int eOrigin, VREvent_t pEvent, int uncbVREvent, TrackedDevicePose_t pTrackedDevicePose);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1371</i> */
+	public interface GetEventTypeNameFromEnum_callback extends Callback {
+		Pointer apply(int eType);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1372</i> */
+	public interface GetHiddenAreaMesh_callback extends Callback {
+		com.jme3.system.jopenvr.HiddenAreaMesh_t.ByValue apply(int eEye, int type);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1373</i> */
+	public interface GetControllerState_callback extends Callback {
+		byte apply(int unControllerDeviceIndex, VRControllerState_t pControllerState, int unControllerStateSize);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1374</i> */
+	public interface GetControllerStateWithPose_callback extends Callback {
+		byte apply(int eOrigin, int unControllerDeviceIndex, VRControllerState_t pControllerState, int unControllerStateSize, TrackedDevicePose_t pTrackedDevicePose);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1375</i> */
+	public interface TriggerHapticPulse_callback extends Callback {
+		void apply(int unControllerDeviceIndex, int unAxisId, short usDurationMicroSec);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1376</i> */
+	public interface GetButtonIdNameFromEnum_callback extends Callback {
+		Pointer apply(int eButtonId);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1377</i> */
+	public interface GetControllerAxisTypeNameFromEnum_callback extends Callback {
+		Pointer apply(int eAxisType);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1378</i> */
+	public interface CaptureInputFocus_callback extends Callback {
+		byte apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1379</i> */
+	public interface ReleaseInputFocus_callback extends Callback {
+		void apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1380</i> */
+	public interface IsInputFocusCapturedByAnotherProcess_callback extends Callback {
+		byte apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1381</i> */
+	public interface DriverDebugRequest_callback extends Callback {
+		int apply(int unDeviceIndex, Pointer pchRequest, Pointer pchResponseBuffer, int unResponseBufferSize);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1382</i> */
+	public interface PerformFirmwareUpdate_callback extends Callback {
+		int apply(int unDeviceIndex);
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1383</i> */
+	public interface AcknowledgeQuit_Exiting_callback extends Callback {
+		void apply();
+	};
+	/** <i>native declaration : headers\openvr_capi.h:1384</i> */
+	public interface AcknowledgeQuit_UserPrompt_callback extends Callback {
+		void apply();
+	};
+	public VR_IVRSystem_FnTable() {
+		super();
+	}
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("GetRecommendedRenderTargetSize", "GetProjectionMatrix", "GetProjectionRaw", "ComputeDistortion", "GetEyeToHeadTransform", "GetTimeSinceLastVsync", "GetD3D9AdapterIndex", "GetDXGIOutputInfo", "IsDisplayOnDesktop", "SetDisplayVisibility", "GetDeviceToAbsoluteTrackingPose", "ResetSeatedZeroPose", "GetSeatedZeroPoseToStandingAbsoluteTrackingPose", "GetRawZeroPoseToStandingAbsoluteTrackingPose", "GetSortedTrackedDeviceIndicesOfClass", "GetTrackedDeviceActivityLevel", "ApplyTransform", "GetTrackedDeviceIndexForControllerRole", "GetControllerRoleForTrackedDeviceIndex", "GetTrackedDeviceClass", "IsTrackedDeviceConnected", "GetBoolTrackedDeviceProperty", "GetFloatTrackedDeviceProperty", "GetInt32TrackedDeviceProperty", "GetUint64TrackedDeviceProperty", "GetMatrix34TrackedDeviceProperty", "GetStringTrackedDeviceProperty", "GetPropErrorNameFromEnum", "PollNextEvent", "PollNextEventWithPose", "GetEventTypeNameFromEnum", "GetHiddenAreaMesh", "GetControllerState", "GetControllerStateWithPose", "TriggerHapticPulse", "GetButtonIdNameFromEnum", "GetControllerAxisTypeNameFromEnum", "CaptureInputFocus", "ReleaseInputFocus", "IsInputFocusCapturedByAnotherProcess", "DriverDebugRequest", "PerformFirmwareUpdate", "AcknowledgeQuit_Exiting", "AcknowledgeQuit_UserPrompt");
+	}
+	public VR_IVRSystem_FnTable(Pointer peer) {
+		super(peer);
+	}
+	public static class ByReference extends VR_IVRSystem_FnTable implements Structure.ByReference {
+		
+	};
+	public static class ByValue extends VR_IVRSystem_FnTable implements Structure.ByValue {
+		
+	};
+}

部分文件因文件數量過多而無法顯示