/* * Copyright 2016 MovingBlocks * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.terasology.rendering.openvrprovider; import jopenvr.HmdMatrix34_t; import jopenvr.HmdMatrix44_t; import jopenvr.VRControllerAxis_t; import jopenvr.VRControllerState_t; 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 { // Controllers private static Matrix4f[] controllerPose = new Matrix4f[2]; private static VRControllerState_t[] lastControllerState = new VRControllerState_t[2]; private List<ControllerListener> controllerListeners = new ArrayList<>(); // 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 = OpenVRUtil.createIdentityMatrix4f(); OpenVRState() { for (int handIndex = 0; handIndex < 2; handIndex++) { lastControllerState[handIndex] = new VRControllerState_t(); controllerPose[handIndex] = OpenVRUtil.createIdentityMatrix4f(); eyePoses[handIndex] = OpenVRUtil.createIdentityMatrix4f(); projectionMatrices[handIndex] = OpenVRUtil.createIdentityMatrix4f(); for (int i = 0; i < 5; i++) { lastControllerState[handIndex].rAxis[i] = new VRControllerAxis_t(); } } } /** * Add a controller listener. This listener will receive pose and button state updates for the controller. * @param listener - An object implementing the ControllerListener interface. */ public void addControllerListener(ControllerListener listener) { controllerListeners.add(listener); } /** * Get the pose of an eye. * @param eyeIndex - An integer specifying the eye: 0 for the left eye, 1 for the right eye. * @return the pose, as a Matrix4f */ public Matrix4f getEyePose(int eyeIndex) { Matrix4f matrixReturn = new Matrix4f(headPose); matrixReturn.mul(eyePoses[eyeIndex]); return matrixReturn; } /** * Get the projection matrix for an eye. * @param eyeIndex - An integer specifying the eye: 0 for the left eye, 1 for the right eye. * @return the projection matrix, as a Matrix4f. */ public Matrix4f getEyeProjectionMatrix(int eyeIndex) { return new Matrix4f(projectionMatrices[eyeIndex]); } void setHeadPose(HmdMatrix34_t inputPose) { OpenVRUtil.setSteamVRMatrix3ToMatrix4f(inputPose, headPose); } void setEyePoseWRTHead(HmdMatrix34_t inputPose, int nIndex) { OpenVRUtil.setSteamVRMatrix3ToMatrix4f(inputPose, eyePoses[nIndex]); } void setControllerPose(HmdMatrix34_t inputPose, int nIndex) { OpenVRUtil.setSteamVRMatrix3ToMatrix4f(inputPose, controllerPose[nIndex]); for (ControllerListener listener : controllerListeners) { listener.poseChanged(controllerPose[nIndex], nIndex); } } void updateControllerButtonState( VRControllerState_t[] controllerStateReference) { // each controller{ for (int handIndex = 0; handIndex < 2; handIndex++) { // store previous state if (lastControllerState[handIndex].ulButtonPressed != controllerStateReference[handIndex].ulButtonPressed) { for (ControllerListener listener : controllerListeners) { listener.buttonStateChanged(lastControllerState[handIndex], controllerStateReference[handIndex], handIndex); } } lastControllerState[handIndex].unPacketNum = controllerStateReference[handIndex].unPacketNum; lastControllerState[handIndex].ulButtonPressed = controllerStateReference[handIndex].ulButtonPressed; lastControllerState[handIndex].ulButtonTouched = controllerStateReference[handIndex].ulButtonTouched; // 5 axes but only [0] and [1] is anything, trigger and touchpad for (int i = 0; i < 5; i++) { if (controllerStateReference[handIndex].rAxis[i] != null) { lastControllerState[handIndex].rAxis[i].x = controllerStateReference[handIndex].rAxis[i].x; lastControllerState[handIndex].rAxis[i].y = controllerStateReference[handIndex].rAxis[i].y; } } } } void setProjectionMatrix( HmdMatrix44_t inputPose, int eyeIndex) { OpenVRUtil.setSteamVRMatrix44ToMatrix4f(inputPose, projectionMatrices[eyeIndex]); } }