Added jopenvrwrapper.

develop
indianajohn 2016-09-11 16:17:10 -07:00
parent 4b48a0ccf5
commit ee3c9317e1
21 changed files with 715 additions and 0 deletions

View File

@ -105,6 +105,7 @@ dependencies {
compile group: 'org.lwjgl.lwjgl', name: 'lwjgl', version: LwjglVersion
compile group: 'org.lwjgl.lwjgl', name: 'lwjgl_util', version: LwjglVersion
compile group: 'java3d', name: 'vecmath', version: '1.3.1' // Note: Downgraded to this release until TeraMath ready
compile "org.joml:joml:1.8.1"
compile group: 'org.abego.treelayout', name: 'org.abego.treelayout.core', version: '1.0.3'
compile group: 'com.miglayout', name: 'miglayout-core', version: '5.0'
compile group: 'de.matthiasmann.twl', name: 'PNGDecoder', version: '1111'

View File

@ -0,0 +1,20 @@
package openvrprovider;
import jopenvr.JOpenVRLibrary;
import jopenvr.VRControllerState_t;
/* Interface intended to be front-facing to user for controller interaction. */
public interface ControllerListener {
public final int LEFT_CONTROLLER = 0;
public final int RIGHT_CONTROLLER = 1;
public static int k_EAxis_Trigger = 1;
public static int k_EAxis_TouchPad = 0;
public static long k_buttonTouchpad = (1L << JOpenVRLibrary.EVRButtonId.EVRButtonId_k_EButton_SteamVR_Touchpad);
public static long k_buttonTrigger = (1L << JOpenVRLibrary.EVRButtonId.EVRButtonId_k_EButton_SteamVR_Trigger);
public static long k_buttonAppMenu = (1L << JOpenVRLibrary.EVRButtonId.EVRButtonId_k_EButton_ApplicationMenu);
public static long k_buttonGrip = (1L << JOpenVRLibrary.EVRButtonId.EVRButtonId_k_EButton_Grip);
public static float triggerThreshold = .25f;
public void buttonStateChanged(VRControllerState_t stateBefore, VRControllerState_t stateAfter, int nController);
// TODO: touch, axes
}

View File

@ -0,0 +1,59 @@
package openvrprovider;
/* Mainly used to locate the OpenVR library on different platforms. */
public class OSValidator {
private static final String OS = System.getProperty("os.name").toLowerCase();
private static final String arch = System.getProperty("os.arch");
private static final String userDir = System.getProperty("user.dir");
public static boolean isWin64() {
return (OS.indexOf("win") >= 0 && arch.contains("64"));
}
public static boolean isWin32() {
return (OS.indexOf("win") >= 0 && arch.contains("32"));
}
public static boolean isLinux64() {
return (OS.indexOf("linux") >= 0 && arch.contains("64"));
}
public static boolean isLinux32() {
return (OS.indexOf("linux") >= 0 && arch.contains("32"));
}
public static boolean isMac() {
return (OS.indexOf("mac") >= 0);
}
public static String getOsString() {
if (isWin64())
return new String("win32-x86-64");
else if (isWin32())
return new String("win32-x86");
else if (isLinux64())
return new String("linux-x86-64");
else if (isLinux32())
return new String("linux-x86");
else if (isMac())
return new String("darwin");
return new String("unknown");
}
public static String getLibPath() {
if (getOsString().contains("win"))
return userDir + "\\openvr_natives\\" + getOsString();
return userDir + "/openvr_natives/" + getOsString();
}
}

View File

@ -0,0 +1,332 @@
package openvrprovider;
import com.sun.jna.Memory;
import com.sun.jna.NativeLibrary;
import com.sun.jna.Pointer;
import jopenvr.*;
import jopenvr.JOpenVRLibrary.EVREventType;
import java.nio.IntBuffer;
import static openvrprovider.ControllerListener.LEFT_CONTROLLER;
import static openvrprovider.ControllerListener.RIGHT_CONTROLLER;
/* This class is designed to make all API calls to OpenVR, thereby insulating it from the user. If you're looking to get
* some information from the headset/controllers you should probably look at OpenVRStereoRenderer, ControllerListener,
* or OpenVRState
* */
public class OpenVRProvider {
private static boolean initialized = false;
private static VR_IVRSystem_FnTable vrsystem;
private static VR_IVRCompositor_FnTable vrCompositor;
private static VR_IVROverlay_FnTable vrOverlay;
private static VR_IVRSettings_FnTable vrSettings;
public OpenVRState vrState = new OpenVRState();
private static int[] controllerDeviceIndex = new int[2];
private static VRControllerState_t.ByReference[] inputStateRefernceArray = new VRControllerState_t.ByReference[2];
private static VRControllerState_t[] controllerStateReference = new VRControllerState_t[2];
private static IntBuffer hmdErrorStore;
private static TrackedDevicePose_t.ByReference hmdTrackedDevicePoseReference;
private static TrackedDevicePose_t[] hmdTrackedDevicePoses;
// TextureIDs of framebuffers for each eye
private float nearClip = 0.5f;
private float farClip = 500.0f;
private final static VRTextureBounds_t texBounds = new VRTextureBounds_t();
public static Texture_t texType[] = new Texture_t[2];
private static boolean[] controllerTracking = new boolean[2];
//keyboard
private static boolean keyboardShowing = false;
private static boolean headIsTracking = false;
public boolean init() {
try {
if (!initializeOpenVRLibrary())
return false;
initializeJOpenVR();
initOpenVRCompositor(true);
initOpenVROverlay();
initOpenVROSettings();
} catch (Exception e) {
return false;
}
initialized = true;
return true;
}
public void shutdown() {
initialized = false;
}
public void updateState()
{
if (!initialized)
init();
updatePose();
pollControllers();
pollInputEvents();
}
private void pollControllers() {
for (int c = 0; c < 2; c++) {
if (controllerDeviceIndex[c] != -1) {
vrsystem.GetControllerState.apply(controllerDeviceIndex[c], inputStateRefernceArray[c]);
inputStateRefernceArray[c].read();
controllerStateReference[c] = inputStateRefernceArray[c];
vrState.updateControllerButtonState(controllerStateReference);
}
}
}
private boolean initializeOpenVRLibrary() throws Exception {
if (initialized)
return true;
System.out.println("Adding OpenVR search path: " + OSValidator.getLibPath());
NativeLibrary.addSearchPath("openvr_api", OSValidator.getLibPath());
if (jopenvr.JOpenVRLibrary.VR_IsHmdPresent() == 1) {
System.out.println("VR Headset detected.");
} else {
System.out.println("VR Headset not detected.");
return false;
}
return true;
}
public OpenVRProvider() {
for (int c = 0; c < 2; c++) {
controllerDeviceIndex[c] = -1;
controllerStateReference[c] = new VRControllerState_t();
inputStateRefernceArray[c] = new VRControllerState_t.ByReference();
inputStateRefernceArray[c].setAutoRead(false);
inputStateRefernceArray[c].setAutoWrite(false);
inputStateRefernceArray[c].setAutoSynch(false);
texType[c] = new Texture_t();
}
}
private static void initializeJOpenVR() throws Exception {
hmdErrorStore = IntBuffer.allocate(1);
vrsystem = null;
JOpenVRLibrary.VR_InitInternal(hmdErrorStore, JOpenVRLibrary.EVRApplicationType.EVRApplicationType_VRApplication_Scene);
if (hmdErrorStore.get(0) == 0) {
// ok, try and get the vrsystem pointer..
vrsystem = new VR_IVRSystem_FnTable(JOpenVRLibrary.VR_GetGenericInterface(JOpenVRLibrary.IVRSystem_Version, hmdErrorStore));
}
if (vrsystem == null || hmdErrorStore.get(0) != 0) {
throw new Exception(jopenvr.JOpenVRLibrary.VR_GetVRInitErrorAsEnglishDescription(hmdErrorStore.get(0)).getString(0));
} else {
vrsystem.setAutoSynch(false);
vrsystem.read();
System.out.println("OpenVR initialized & VR connected.");
hmdTrackedDevicePoseReference = new TrackedDevicePose_t.ByReference();
hmdTrackedDevicePoses = (TrackedDevicePose_t[]) hmdTrackedDevicePoseReference.toArray(JOpenVRLibrary.k_unMaxTrackedDeviceCount);
// 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);
}
}
}
// needed for in-game keyboard
private static void initOpenVROverlay() throws Exception {
vrOverlay = new VR_IVROverlay_FnTable(JOpenVRLibrary.VR_GetGenericInterface(JOpenVRLibrary.IVROverlay_Version, hmdErrorStore));
if (hmdErrorStore.get(0) == 0) {
vrOverlay.setAutoSynch(false);
vrOverlay.read();
System.out.println("OpenVR Overlay initialized OK");
} else {
throw new Exception(jopenvr.JOpenVRLibrary.VR_GetVRInitErrorAsEnglishDescription(hmdErrorStore.get(0)).getString(0));
}
}
private static void initOpenVROSettings() throws Exception {
vrSettings = new VR_IVRSettings_FnTable(JOpenVRLibrary.VR_GetGenericInterface(JOpenVRLibrary.IVRSettings_Version, hmdErrorStore));
if (hmdErrorStore.get(0) == 0) {
vrSettings.setAutoSynch(false);
vrSettings.read();
System.out.println("OpenVR Settings initialized OK");
} else {
throw new Exception(jopenvr.JOpenVRLibrary.VR_GetVRInitErrorAsEnglishDescription(hmdErrorStore.get(0)).getString(0));
}
}
private static void initOpenVRCompositor(boolean set) throws Exception {
if (set && vrsystem != null) {
vrCompositor = new VR_IVRCompositor_FnTable(JOpenVRLibrary.VR_GetGenericInterface(JOpenVRLibrary.IVRCompositor_Version, hmdErrorStore));
if (hmdErrorStore.get(0) == 0) {
System.out.println("OpenVR Compositor initialized OK.");
vrCompositor.setAutoSynch(false);
vrCompositor.read();
vrCompositor.SetTrackingSpace.apply(JOpenVRLibrary.ETrackingUniverseOrigin.ETrackingUniverseOrigin_TrackingUniverseStanding);
} else {
throw new Exception(jopenvr.JOpenVRLibrary.VR_GetVRInitErrorAsEnglishDescription(hmdErrorStore.get(0)).getString(0));
}
}
if (vrCompositor == null) {
System.out.println("Skipping VR Compositor...");
}
// left eye
texBounds.uMax = 1f;
texBounds.uMin = 0f;
texBounds.vMax = 1f;
texBounds.vMin = 0f;
texBounds.setAutoSynch(false);
texBounds.setAutoRead(false);
texBounds.setAutoWrite(false);
texBounds.write();
// texture type
for (int nEye = 0; nEye < 2; nEye++) {
texType[0].eColorSpace = JOpenVRLibrary.EColorSpace.EColorSpace_ColorSpace_Gamma;
texType[0].eType = JOpenVRLibrary.EGraphicsAPIConvention.EGraphicsAPIConvention_API_OpenGL;
texType[0].setAutoSynch(false);
texType[0].setAutoRead(false);
texType[0].setAutoWrite(false);
texType[0].handle = -1;
texType[0].write();
}
System.out.println("OpenVR Compositor initialized OK.");
}
public static boolean setKeyboardOverlayShowing(boolean showingState) {
int ret = 1;
if (showingState) {
Pointer pointer = new Memory(3);
pointer.setString(0, "mc");
Pointer empty = new Memory(1);
empty.setString(0, "");
ret = vrOverlay.ShowKeyboard.apply(0, 0, pointer, 256, empty, (byte) 1, 0);
keyboardShowing = 0 == ret; //0 = no error, > 0 see EVROverlayError
if (ret != 0) {
System.out.println("VR Overlay Error: " + vrOverlay.GetOverlayErrorNameFromEnum.apply(ret).getString(0));
}
} else {
try {
vrOverlay.HideKeyboard.apply();
} catch (Error e) {
}
keyboardShowing = false;
}
return keyboardShowing;
}
public void destroy() {
if (this.initialized) {
JOpenVRLibrary.VR_ShutdownInternal();
this.initialized = false;
}
}
private static void findControllerDevices() {
controllerDeviceIndex[RIGHT_CONTROLLER] = -1;
controllerDeviceIndex[LEFT_CONTROLLER] = -1;
controllerDeviceIndex[RIGHT_CONTROLLER] = vrsystem.GetTrackedDeviceIndexForControllerRole.apply(JOpenVRLibrary.ETrackedControllerRole.ETrackedControllerRole_TrackedControllerRole_LeftHand);
controllerDeviceIndex[LEFT_CONTROLLER] = vrsystem.GetTrackedDeviceIndexForControllerRole.apply(JOpenVRLibrary.ETrackedControllerRole.ETrackedControllerRole_TrackedControllerRole_RightHand);
}
//jrbuda:: oh hello there you are.
private static void pollInputEvents() {
if (vrsystem == null) return;
jopenvr.VREvent_t event = new jopenvr.VREvent_t();
while (vrsystem.PollNextEvent.apply(event, event.size()) > 0) {
switch (event.eventType) {
case EVREventType.EVREventType_VREvent_KeyboardClosed:
//'huzzah'
keyboardShowing = false;
break;
case EVREventType.EVREventType_VREvent_KeyboardCharInput:
byte[] inbytes = event.data.getPointer().getByteArray(0, 8);
int len = 0;
for (byte b : inbytes) {
if (b > 0) len++;
}
break;
default:
break;
}
}
}
private void updatePose() {
if (vrsystem == null || vrCompositor == null)
return;
vrCompositor.WaitGetPoses.apply(hmdTrackedDevicePoseReference, JOpenVRLibrary.k_unMaxTrackedDeviceCount, null, 0);
for (int nDevice = 0; nDevice < JOpenVRLibrary.k_unMaxTrackedDeviceCount; ++nDevice) {
hmdTrackedDevicePoses[nDevice].read();
}
if (hmdTrackedDevicePoses[JOpenVRLibrary.k_unTrackedDeviceIndex_Hmd].bPoseIsValid != 0) {
for (int nEye = 0; nEye < 2; nEye++) {
HmdMatrix34_t matPose = vrsystem.GetEyeToHeadTransform.apply(nEye);
vrState.setEyePoseWRTHead(matPose, nEye);
HmdMatrix44_t matProjection = vrsystem.GetProjectionMatrix.apply(nEye, nearClip, farClip, JOpenVRLibrary.EGraphicsAPIConvention.EGraphicsAPIConvention_API_OpenGL);
vrState.setProjectionMatrix(matProjection, nEye);
}
vrState.setHeadPose(hmdTrackedDevicePoses[JOpenVRLibrary.k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking);
headIsTracking = true;
} else {
headIsTracking = false;
}
findControllerDevices();
for (int c = 0; c < 2; c++) {
if (controllerDeviceIndex[c] != -1) {
controllerTracking[c] = true;
vrState.setControllerPose(hmdTrackedDevicePoses[controllerDeviceIndex[c]].mDeviceToAbsoluteTracking, c);
} else {
controllerTracking[c] = false;
}
}
}
public static void triggerHapticPulse(int controller, int strength) {
if (controllerDeviceIndex[controller] == -1)
return;
vrsystem.TriggerHapticPulse.apply(controllerDeviceIndex[controller], 0, (short) strength);
}
public void submitFrame() {
if (vrCompositor == null) return;
if (vrCompositor.Submit == null) return;
for (int nEye = 0; nEye < 2; nEye++) {
int ret = vrCompositor.Submit.apply(
nEye,
texType[nEye], null,
JOpenVRLibrary.EVRSubmitFlags.EVRSubmitFlags_Submit_Default);
}
if (vrCompositor.PostPresentHandoff != null)
vrCompositor.PostPresentHandoff.apply();
}
public void setNearClip(float _nearClip) {
nearClip = _nearClip;
}
public void setFarClip(float _farClip) {
farClip = _farClip;
}
}

View File

@ -0,0 +1,99 @@
package openvrprovider;
import jopenvr.*;
import org.joml.Matrix4f;
import java.util.ArrayList;
import java.util.List;
/* Contains all of the information that the user will need from OpenVR without using any OpenVR data structures. The
OpenVRProvider automatically updates this.
*/
public class OpenVRState {
public static int LEFT_EYE = JOpenVRLibrary.EVREye.EVREye_Eye_Left;
public static int RIGHT_EYE = JOpenVRLibrary.EVREye.EVREye_Eye_Right;
private List<ControllerListener> controllerListeners = new ArrayList<>();
public void addControllerListener(ControllerListener toAdd) {
controllerListeners.add(toAdd);
}
// In the head frame
private Matrix4f[] eyePoses = new Matrix4f[2];
private Matrix4f[] projectionMatrices = new Matrix4f[2];
// In the tracking system intertial frame
private Matrix4f headPose = new Matrix4f(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
// Controllers
private static Matrix4f[] controllerPose = new Matrix4f[2];
private static VRControllerState_t[] lastControllerState = new VRControllerState_t[2];
OpenVRState() {
for (int c = 0; c < 2; c++) {
lastControllerState[c] = new VRControllerState_t();
controllerPose[c] = new Matrix4f(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
eyePoses[c] = new Matrix4f(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
projectionMatrices[c] = new Matrix4f(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
for (int i = 0; i < 5; i++) {
lastControllerState[c].rAxis[i] = new VRControllerAxis_t();
}
}
}
public void setHeadPose(HmdMatrix34_t inputPose) {
OpenVRUtil.setSteamVRMatrix3ToMatrix4f(inputPose, headPose);
}
public void setEyePoseWRTHead(HmdMatrix34_t inputPose, int nIndex) {
OpenVRUtil.setSteamVRMatrix3ToMatrix4f(inputPose, eyePoses[nIndex]);
}
public void setControllerPose(HmdMatrix34_t inputPose, int nIndex) {
OpenVRUtil.setSteamVRMatrix3ToMatrix4f(inputPose, controllerPose[nIndex]);
}
public Matrix4f getEyePose(int nEye) {
Matrix4f matrixReturn = new Matrix4f(headPose);
matrixReturn.mul(eyePoses[nEye]);
return matrixReturn;
}
public Matrix4f getEyeProjectionMatrix(int nEye) {
return new Matrix4f(projectionMatrices[nEye]);
}
public void updateControllerButtonState(
VRControllerState_t[] controllerStateReference) {
for (int c = 0; c < 2; c++) //each controller
{
// store previous state
if (lastControllerState[c].ulButtonPressed != controllerStateReference[c].ulButtonPressed) {
for (ControllerListener listener : controllerListeners) {
listener.buttonStateChanged(lastControllerState[c], controllerStateReference[c], c);
}
}
lastControllerState[c].unPacketNum = controllerStateReference[c].unPacketNum;
lastControllerState[c].ulButtonPressed = controllerStateReference[c].ulButtonPressed;
lastControllerState[c].ulButtonTouched = controllerStateReference[c].ulButtonTouched;
for (int i = 0; i < 5; i++) //5 axes but only [0] and [1] is anything, trigger and touchpad
{
if (controllerStateReference[c].rAxis[i] != null) {
lastControllerState[c].rAxis[i].x = controllerStateReference[c].rAxis[i].x;
lastControllerState[c].rAxis[i].y = controllerStateReference[c].rAxis[i].y;
}
}
}
}
public void setProjectionMatrix(
HmdMatrix44_t inputPose,
int nEye) {
OpenVRUtil.setSteamVRMatrix44ToMatrix4f(inputPose, projectionMatrices[nEye]);
}
}

View File

@ -0,0 +1,71 @@
package openvrprovider;
import jopenvr.JOpenVRLibrary;
import org.lwjgl.opengl.EXTFramebufferObject;
import org.lwjgl.opengl.GL11;
import static org.lwjgl.opengl.EXTFramebufferObject.*;
import static org.lwjgl.opengl.GL11.GL_DEPTH_COMPONENT;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
/* This class is designed to manage the framebuffers for the headset. */
public class OpenVRStereoRenderer {
public OpenVRProvider vrProvider;
// TextureIDs of framebuffers for each eye
private int eyeTextureIDs[] = new int[2];
private int eyeFBOIds[] = new int[2];
public OpenVRStereoRenderer(OpenVRProvider _vrProvider, int lwidth, int lheight) {
vrProvider = _vrProvider;
createRenderTexture(lwidth, lheight);
}
public void deleteRenderTextures() {
if (eyeTextureIDs[0] > 0) GL11.glDeleteTextures(eyeTextureIDs[0]);
}
public void createRenderTexture(int lwidth, int lheight) {
for (int nEye = 0; nEye < 2; nEye++) {
eyeFBOIds[nEye] = glGenFramebuffersEXT();
EXTFramebufferObject.glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, eyeFBOIds[nEye]);
//depth buffer
int depthbuffer = glGenRenderbuffersEXT();
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthbuffer);
//allocate space for the renderbuffer
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, lwidth, lheight);
//attach depth buffer to fbo
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthbuffer);
eyeTextureIDs[nEye] = GL11.glGenTextures();
int boundTextureId = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D);
GL11.glBindTexture(GL_TEXTURE_2D, eyeTextureIDs[nEye]);
GL11.glEnable(GL_TEXTURE_2D);
GL11.glTexParameterf(GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL11.glTexParameterf(GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexImage2D(GL_TEXTURE_2D, 0, GL11.GL_RGBA8, lwidth, lheight, 0, GL11.GL_RGBA, GL11.GL_INT, (java.nio.ByteBuffer) null);
GL11.glBindTexture(GL_TEXTURE_2D, boundTextureId);
//attach texture to the fbo
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, eyeTextureIDs[nEye], 0);
//check completeness
if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) {
System.out.println("An error occured creating the frame buffer.");
}
vrProvider.texType[nEye].handle = eyeTextureIDs[nEye];
vrProvider.texType[nEye].eColorSpace = JOpenVRLibrary.EColorSpace.EColorSpace_ColorSpace_Gamma;
vrProvider.texType[nEye].eType = JOpenVRLibrary.EGraphicsAPIConvention.EGraphicsAPIConvention_API_OpenGL;
vrProvider.texType[nEye].write();
}
}
public int getTextureHandleForEyeFramebuffer(int nEye) {
return eyeFBOIds[nEye];
}
}

View File

@ -0,0 +1,93 @@
package openvrprovider;
import jopenvr.HmdMatrix34_t;
import jopenvr.HmdMatrix44_t;
import jopenvr.VRControllerState_t;
import org.joml.Matrix4f;
import java.util.concurrent.TimeUnit;
/* Utility functions that don't interact with the headset (conversions and the like) */
public class OpenVRUtil {
private static final long SLEEP_PRECISION = TimeUnit.MILLISECONDS.toNanos(4);
private static final long SPIN_YIELD_PRECISION = TimeUnit.MILLISECONDS.toNanos(2);
public static Matrix4f convertSteamVRMatrix3ToMatrix4f(HmdMatrix34_t hmdMatrix) {
return new Matrix4f(
hmdMatrix.m[0], hmdMatrix.m[4], hmdMatrix.m[8], 0,
hmdMatrix.m[1], hmdMatrix.m[5], hmdMatrix.m[9], 0,
hmdMatrix.m[2], hmdMatrix.m[6], hmdMatrix.m[10], 0,
hmdMatrix.m[3], hmdMatrix.m[7], hmdMatrix.m[11], 1f
);
}
public static Matrix4f convertSteamVRMatrix44ToMatrix4f(HmdMatrix44_t hmdMatrix) {
return new Matrix4f(
hmdMatrix.m[0], hmdMatrix.m[4], hmdMatrix.m[8], hmdMatrix.m[12],
hmdMatrix.m[1], hmdMatrix.m[5], hmdMatrix.m[9], hmdMatrix.m[13],
hmdMatrix.m[2], hmdMatrix.m[6], hmdMatrix.m[10], hmdMatrix.m[14],
hmdMatrix.m[3], hmdMatrix.m[7], hmdMatrix.m[11], hmdMatrix.m[15]
);
}
public static void setSteamVRMatrix3ToMatrix4f(HmdMatrix34_t hmdMatrix, Matrix4f matrixToSet) {
matrixToSet.set(
hmdMatrix.m[0], hmdMatrix.m[4], hmdMatrix.m[8], 0,
hmdMatrix.m[1], hmdMatrix.m[5], hmdMatrix.m[9], 0,
hmdMatrix.m[2], hmdMatrix.m[6], hmdMatrix.m[10], 0,
hmdMatrix.m[3], hmdMatrix.m[7], hmdMatrix.m[11], 1f
);
}
public static void setSteamVRMatrix44ToMatrix4f(HmdMatrix44_t hmdMatrix, Matrix4f matrixToSet) {
matrixToSet.set(
hmdMatrix.m[0], hmdMatrix.m[4], hmdMatrix.m[8], hmdMatrix.m[12],
hmdMatrix.m[1], hmdMatrix.m[5], hmdMatrix.m[9], hmdMatrix.m[13],
hmdMatrix.m[2], hmdMatrix.m[6], hmdMatrix.m[10], hmdMatrix.m[14],
hmdMatrix.m[3], hmdMatrix.m[7], hmdMatrix.m[11], hmdMatrix.m[15]
);
}
public static void sleepNanos(long nanoDuration) {
final long end = System.nanoTime() + nanoDuration;
long timeLeft = nanoDuration;
do {
try {
if (timeLeft > SLEEP_PRECISION) {
Thread.sleep(1);
} else if (timeLeft > SPIN_YIELD_PRECISION) {
Thread.sleep(0);
}
} catch (Exception e) {
}
timeLeft = end - System.nanoTime();
} while (timeLeft > 0);
}
public static VRControllerState_t createZeroControllerState() {
VRControllerState_t state = new VRControllerState_t();
// controller not connected, clear state
state.ulButtonPressed = 0;
for (int i = 0; i < 5; i++) {
if (state.rAxis[i] != null) {
state.rAxis[i].x = 0.0f;
state.rAxis[i].y = 0.0f;
}
}
return state;
}
public static boolean isPressed(long nButton, long uiButtonPressed) {
return ((uiButtonPressed & nButton) > 0);
}
public static boolean switchedDown(long nButton, long stateBefore, long stateAfter) {
return (!isPressed(nButton, stateBefore) && isPressed(nButton, stateAfter));
}
public static boolean switchedUp(long nButton, long stateBefore, long stateAfter) {
return (isPressed(nButton, stateBefore) && !isPressed(nButton, stateAfter));
}
}

Binary file not shown.

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.libopenvr_api.dylib</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.libopenvr_api.dylib</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.