rm openvr;

This commit is contained in:
bjorn 2022-03-22 14:09:11 -07:00
parent 2da18d419b
commit b9889ca97a
26 changed files with 2 additions and 1784 deletions

3
.gitmodules vendored
View File

@ -10,9 +10,6 @@
[submodule "deps/ode"]
path = deps/ode
url = https://github.com/bjornbytes/ode
[submodule "deps/openvr"]
path = deps/openvr
url = https://github.com/ValveSoftware/openvr
[submodule "deps/luajit"]
path = deps/luajit
url = https://github.com/WohlSoft/LuaJIT

View File

@ -16,7 +16,6 @@ option(LOVR_ENABLE_THREAD "Enable the thread module" ON)
option(LOVR_ENABLE_TIMER "Enable the timer module" ON)
option(LOVR_USE_LUAJIT "Use LuaJIT instead of Lua" ON)
option(LOVR_USE_OPENVR "Enable the OpenVR backend for the headset module" OFF)
option(LOVR_USE_OPENXR "Enable the OpenXR backend for the headset module" ON)
option(LOVR_USE_WEBXR "Enable the WebXR backend for the headset module" OFF)
option(LOVR_USE_OCULUS "Enable the LibOVR backend for the headset module (be sure to also set LOVR_OCULUS_PATH to point to the Oculus SDK)" OFF)
@ -57,7 +56,6 @@ if(EMSCRIPTEN)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LOVR_EMSCRIPTEN_FLAGS}")
set(CMAKE_EXECUTABLE_SUFFIX ".html")
set(LOVR_USE_WEBXR ON)
set(LOVR_USE_OPENVR OFF)
elseif(ANDROID)
find_package(Java REQUIRED)
set(LOVR_USE_DESKTOP OFF)
@ -175,25 +173,6 @@ if(NOT (WIN32 OR EMSCRIPTEN OR ANDROID))
set(LOVR_OPENGL ${OPENGL_LIBRARIES})
endif()
# OpenVR
if(LOVR_ENABLE_HEADSET AND LOVR_USE_OPENVR)
set(BUILD_SHARED ON CACHE BOOL "")
set(BUILD_UNIVERSAL OFF CACHE BOOL "")
include_directories(deps/openvr/headers)
include_directories(deps/openvr/src)
include_directories(deps/openvr/src/vrcommon)
if(WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 8)
set(LOVR_OPENVR openvr_api64)
else()
set(LOVR_OPENVR openvr_api)
endif()
add_subdirectory(deps/openvr)
set_target_properties(${LOVR_OPENVR} PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/openvr_api"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/openvr_api"
)
endif()
# OpenXR
if(LOVR_ENABLE_HEADSET AND LOVR_USE_OPENXR)
include_directories(deps/openxr/include)
@ -374,7 +353,6 @@ target_link_libraries(lovr
${LOVR_MSDF}
${LOVR_ODE}
${LOVR_OPENGL}
${LOVR_OPENVR}
${LOVR_OPENXR}
${LOVR_OCULUS}
${LOVR_OCULUS_AUDIO}
@ -493,10 +471,6 @@ if(LOVR_ENABLE_HEADSET)
src/modules/headset/headset.c
)
if(LOVR_USE_OPENVR)
target_compile_definitions(lovr PRIVATE LOVR_USE_OPENVR)
target_sources(lovr PRIVATE src/modules/headset/headset_openvr.c)
endif()
if(LOVR_USE_OPENXR)
target_compile_definitions(lovr PRIVATE LOVR_USE_OPENXR)
target_sources(lovr PRIVATE src/modules/headset/headset_openxr.c)
@ -583,7 +557,7 @@ else()
endif()
# Resources
file(GLOB LOVR_RESOURCES "src/resources/*.ttf" "src/resources/*.json" "src/resources/*.lua")
file(GLOB LOVR_RESOURCES "src/resources/*.ttf" "src/resources/*.lua")
foreach(path ${LOVR_RESOURCES})
# Turn the absolute path into a C variable like src_resources_boot_lua
@ -634,7 +608,6 @@ if(WIN32)
move_dll(${LOVR_GLFW})
move_dll(${LOVR_LUA})
move_dll(${LOVR_ODE})
move_dll(${LOVR_OPENVR})
move_dll(${LOVR_MSDF})
move_dll(${LOVR_OCULUS_AUDIO})
move_dll(${LOVR_PHONON})
@ -686,7 +659,6 @@ elseif(APPLE)
move_lib(${LOVR_GLFW})
move_lib(${LOVR_LUA})
move_lib(${LOVR_ODE})
move_lib(${LOVR_OPENVR})
move_lib(${LOVR_MSDF})
move_lib(${LOVR_OCULUS_AUDIO})
move_lib(${LOVR_PHONON})
@ -860,7 +832,6 @@ elseif(UNIX)
move_lib(${LOVR_GLFW})
move_lib(${LOVR_LUA})
move_lib(${LOVR_ODE})
move_lib(${LOVR_OPENVR})
move_lib(${LOVR_MSDF})
move_lib(${LOVR_OCULUS_AUDIO})
foreach(target ${ALL_PLUGIN_TARGETS})

View File

@ -23,7 +23,6 @@ config = {
},
headsets = {
desktop = true,
openvr = false,
openxr = false, -- if provided, should be path to folder containing OpenXR loader library
oculus = false,
vrapi = false,
@ -175,7 +174,6 @@ end
overrides = {
glad = '-Wno-pedantic',
os_android = '-Wno-format-pedantic',
openvr = '-Wno-unused-variable -Wno-typedef-redefinition -Wno-pedantic',
vrapi = '-Wno-c11-extensions -Wno-gnu-empty-initializer -Wno-pedantic',
miniaudio = '-Wno-unused-function',
}
@ -310,18 +308,6 @@ if config.modules.physics then
tup.rule('.obj/ode/*.o', '^ LD %o^ $(cxx) $(base_flags) -shared -static-libstdc++ -o %o %f', lib('ode'))
end
if config.headsets.openvr then
cflags_openvr += '-Ideps/openvr/headers'
lflags += '-lopenvr_api'
openvr_libs = {
win32 = 'deps/openvr/bin/win64/openvr_api.dll',
macos = 'deps/openvr/bin/osx32/openvr_api.dll',
linux = 'deps/openvr/bin/linux64/libopenvr_api.so'
}
assert(openvr_libs[target], 'OpenVR is not supported on this target')
copy(openvr_libs[target], '$(bin)/%b')
end
if config.headsets.openxr then
if target == 'android' then
cflags_headset_openxr += '-Ideps/openxr/include'
@ -444,7 +430,6 @@ src += config.modules.thread and 'src/lib/tinycthread/*.c' or nil
res += 'src/resources/*.lua'
res += 'src/resources/*.ttf'
res += 'src/resources/*.json'
for i = 1, #res do
src.extra_inputs += res[i] .. '.h'

1
deps/openvr vendored

@ -1 +0,0 @@
Subproject commit e3d37563fd0405117f035c111346f60ca12625ba

View File

@ -12,7 +12,6 @@
StringEntry lovrHeadsetDriver[] = {
[DRIVER_DESKTOP] = ENTRY("desktop"),
[DRIVER_OCULUS] = ENTRY("oculus"),
[DRIVER_OPENVR] = ENTRY("openvr"),
[DRIVER_OPENXR] = ENTRY("openxr"),
[DRIVER_VRAPI] = ENTRY("vrapi"),
[DRIVER_PICO] = ENTRY("pico"),

View File

@ -21,9 +21,6 @@ bool lovrHeadsetInit(HeadsetDriver* drivers, size_t count, float supersample, fl
#ifdef LOVR_USE_OCULUS
case DRIVER_OCULUS: interface = &lovrHeadsetOculusDriver; break;
#endif
#ifdef LOVR_USE_OPENVR
case DRIVER_OPENVR: interface = &lovrHeadsetOpenVRDriver; break;
#endif
#ifdef LOVR_USE_OPENXR
case DRIVER_OPENXR: interface = &lovrHeadsetOpenXRDriver; break;
#endif

View File

@ -13,7 +13,6 @@ struct Texture;
typedef enum {
DRIVER_DESKTOP,
DRIVER_OCULUS,
DRIVER_OPENVR,
DRIVER_OPENXR,
DRIVER_VRAPI,
DRIVER_PICO,
@ -148,7 +147,6 @@ typedef struct HeadsetInterface {
// Available drivers
extern HeadsetInterface lovrHeadsetOculusDriver;
extern HeadsetInterface lovrHeadsetOpenVRDriver;
extern HeadsetInterface lovrHeadsetOpenXRDriver;
extern HeadsetInterface lovrHeadsetVrApiDriver;
extern HeadsetInterface lovrHeadsetPicoDriver;

View File

@ -1,920 +0,0 @@
#include "headset/headset.h"
#include "resources/actions.json.h"
#include "resources/bindings_vive.json.h"
#include "resources/bindings_knuckles.json.h"
#include "resources/bindings_touch.json.h"
#include "resources/bindings_holographic_controller.json.h"
#include "resources/bindings_vive_tracker_left_elbow.json.h"
#include "resources/bindings_vive_tracker_right_elbow.json.h"
#include "resources/bindings_vive_tracker_left_shoulder.json.h"
#include "resources/bindings_vive_tracker_right_shoulder.json.h"
#include "resources/bindings_vive_tracker_chest.json.h"
#include "resources/bindings_vive_tracker_waist.json.h"
#include "resources/bindings_vive_tracker_left_knee.json.h"
#include "resources/bindings_vive_tracker_right_knee.json.h"
#include "resources/bindings_vive_tracker_left_foot.json.h"
#include "resources/bindings_vive_tracker_right_foot.json.h"
#include "resources/bindings_vive_tracker_camera.json.h"
#include "resources/bindings_vive_tracker_keyboard.json.h"
#include "data/blob.h"
#include "event/event.h"
#include "filesystem/filesystem.h"
#include "graphics/graphics.h"
#include "graphics/canvas.h"
#include "graphics/model.h"
#include "graphics/texture.h"
#include "core/maf.h"
#include "core/os.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#undef EXTERN_C
#include <openvr_capi.h>
// From openvr_capi.h
extern intptr_t VR_InitInternal(EVRInitError *peError, EVRApplicationType eType);
extern void VR_ShutdownInternal();
extern bool VR_IsHmdPresent();
extern intptr_t VR_GetGenericInterface(const char* pchInterfaceVersion, EVRInitError* peError);
extern bool VR_IsRuntimeInstalled();
#define HEADSET k_unTrackedDeviceIndex_Hmd
#define INVALID_DEVICE k_unTrackedDeviceIndexInvalid
enum {
eBone_Root = 0,
eBone_Wrist,
eBone_Thumb0,
eBone_Thumb1,
eBone_Thumb2,
eBone_Thumb3,
eBone_IndexFinger0,
eBone_IndexFinger1,
eBone_IndexFinger2,
eBone_IndexFinger3,
eBone_IndexFinger4,
eBone_MiddleFinger0,
eBone_MiddleFinger1,
eBone_MiddleFinger2,
eBone_MiddleFinger3,
eBone_MiddleFinger4,
eBone_RingFinger0,
eBone_RingFinger1,
eBone_RingFinger2,
eBone_RingFinger3,
eBone_RingFinger4,
eBone_PinkyFinger0,
eBone_PinkyFinger1,
eBone_PinkyFinger2,
eBone_PinkyFinger3,
eBone_PinkyFinger4,
eBone_Aux_Thumb,
eBone_Aux_IndexFinger,
eBone_Aux_MiddleFinger,
eBone_Aux_RingFinger,
eBone_Aux_PinkyFinger,
eBone_Count
};
static struct {
struct VR_IVRSystem_FnTable* system;
struct VR_IVRCompositor_FnTable* compositor;
struct VR_IVRChaperone_FnTable* chaperone;
struct VR_IVRRenderModels_FnTable* renderModels;
struct VR_IVRInput_FnTable* input;
VRActionSetHandle_t actionSet;
VRActionHandle_t poseActions[MAX_DEVICES];
VRActionHandle_t buttonActions[2][MAX_BUTTONS];
VRActionHandle_t touchActions[2][MAX_BUTTONS];
VRActionHandle_t axisActions[2][MAX_AXES];
VRActionHandle_t skeletonActions[2];
VRActionHandle_t hapticActions[2];
VRInputValueHandle_t inputSources[3];
TrackedDevicePose_t renderPoses[64];
Canvas* canvas;
float* mask;
float boundsGeometry[16];
float clipNear;
float clipFar;
float supersample;
float offset;
int msaa;
} state;
static TrackedDeviceIndex_t getDeviceIndex(Device device) {
switch (device) {
case DEVICE_HEAD: return HEADSET;
case DEVICE_HAND_LEFT: return state.system->GetTrackedDeviceIndexForControllerRole(ETrackedControllerRole_TrackedControllerRole_LeftHand);
case DEVICE_HAND_RIGHT: return state.system->GetTrackedDeviceIndexForControllerRole(ETrackedControllerRole_TrackedControllerRole_RightHand);
default: return INVALID_DEVICE;
}
}
static bool openvr_getName(char* name, size_t length);
static bool openvr_init(float supersample, float offset, uint32_t msaa, bool overlay) {
if (!VR_IsHmdPresent() || !VR_IsRuntimeInstalled()) {
return false;
}
EVRInitError vrError;
VR_InitInternal(&vrError, EVRApplicationType_VRApplication_Scene);
if (vrError != EVRInitError_VRInitError_None) {
return false;
}
char buffer[64];
sprintf(buffer, "FnTable:%s", IVRSystem_Version), state.system = (struct VR_IVRSystem_FnTable*) VR_GetGenericInterface(buffer, &vrError);
sprintf(buffer, "FnTable:%s", IVRCompositor_Version), state.compositor = (struct VR_IVRCompositor_FnTable*) VR_GetGenericInterface(buffer, &vrError);
sprintf(buffer, "FnTable:%s", IVRChaperone_Version), state.chaperone = (struct VR_IVRChaperone_FnTable*) VR_GetGenericInterface(buffer, &vrError);
sprintf(buffer, "FnTable:%s", IVRRenderModels_Version), state.renderModels = (struct VR_IVRRenderModels_FnTable*) VR_GetGenericInterface(buffer, &vrError);
sprintf(buffer, "FnTable:%s", IVRInput_Version), state.input = (struct VR_IVRInput_FnTable*) VR_GetGenericInterface(buffer, &vrError);
if (!state.system || !state.compositor || !state.chaperone || !state.renderModels || !state.input) {
VR_ShutdownInternal();
return false;
}
// Find the location of the action manifest, create it if it doesn't exist or isn't in the save directory
const char* actionManifestLocation = lovrFilesystemGetRealDirectory("actions.json");
if (!actionManifestLocation || strcmp(actionManifestLocation, lovrFilesystemGetSaveDirectory())) {
if (
lovrFilesystemWrite("actions.json", (const char*) src_resources_actions_json, src_resources_actions_json_len, false) != src_resources_actions_json_len ||
lovrFilesystemWrite("bindings_vive.json", (const char*) src_resources_bindings_vive_json, src_resources_bindings_vive_json_len, false) != src_resources_bindings_vive_json_len ||
lovrFilesystemWrite("bindings_knuckles.json", (const char*) src_resources_bindings_knuckles_json, src_resources_bindings_knuckles_json_len, false) != src_resources_bindings_knuckles_json_len ||
lovrFilesystemWrite("bindings_touch.json", (const char*) src_resources_bindings_touch_json, src_resources_bindings_touch_json_len, false) != src_resources_bindings_touch_json_len ||
lovrFilesystemWrite("bindings_holographic_controller.json", (const char*) src_resources_bindings_holographic_controller_json, src_resources_bindings_holographic_controller_json_len, false) != src_resources_bindings_holographic_controller_json_len ||
lovrFilesystemWrite("bindings_vive_tracker_left_elbow.json", (const char*) src_resources_bindings_vive_tracker_left_elbow_json, src_resources_bindings_vive_tracker_left_elbow_json_len, false) != src_resources_bindings_vive_tracker_left_elbow_json_len ||
lovrFilesystemWrite("bindings_vive_tracker_right_elbow.json", (const char*) src_resources_bindings_vive_tracker_right_elbow_json, src_resources_bindings_vive_tracker_right_elbow_json_len, false) != src_resources_bindings_vive_tracker_right_elbow_json_len ||
lovrFilesystemWrite("bindings_vive_tracker_left_shoulder.json", (const char*) src_resources_bindings_vive_tracker_left_shoulder_json, src_resources_bindings_vive_tracker_left_shoulder_json_len, false) != src_resources_bindings_vive_tracker_left_shoulder_json_len ||
lovrFilesystemWrite("bindings_vive_tracker_right_shoulder.json", (const char*) src_resources_bindings_vive_tracker_right_shoulder_json, src_resources_bindings_vive_tracker_right_shoulder_json_len, false) != src_resources_bindings_vive_tracker_right_shoulder_json_len ||
lovrFilesystemWrite("bindings_vive_tracker_chest.json", (const char*) src_resources_bindings_vive_tracker_chest_json, src_resources_bindings_vive_tracker_chest_json_len, false) != src_resources_bindings_vive_tracker_chest_json_len ||
lovrFilesystemWrite("bindings_vive_tracker_waist.json", (const char*) src_resources_bindings_vive_tracker_waist_json, src_resources_bindings_vive_tracker_waist_json_len, false) != src_resources_bindings_vive_tracker_waist_json_len ||
lovrFilesystemWrite("bindings_vive_tracker_left_knee.json", (const char*) src_resources_bindings_vive_tracker_left_knee_json, src_resources_bindings_vive_tracker_left_knee_json_len, false) != src_resources_bindings_vive_tracker_left_knee_json_len ||
lovrFilesystemWrite("bindings_vive_tracker_right_knee.json", (const char*) src_resources_bindings_vive_tracker_right_knee_json, src_resources_bindings_vive_tracker_right_knee_json_len, false) != src_resources_bindings_vive_tracker_right_knee_json_len ||
lovrFilesystemWrite("bindings_vive_tracker_left_foot.json", (const char*) src_resources_bindings_vive_tracker_left_foot_json, src_resources_bindings_vive_tracker_left_foot_json_len, false) != src_resources_bindings_vive_tracker_left_foot_json_len ||
lovrFilesystemWrite("bindings_vive_tracker_right_foot.json", (const char*) src_resources_bindings_vive_tracker_right_foot_json, src_resources_bindings_vive_tracker_right_foot_json_len, false) != src_resources_bindings_vive_tracker_right_foot_json_len ||
lovrFilesystemWrite("bindings_vive_tracker_camera.json", (const char*) src_resources_bindings_vive_tracker_camera_json, src_resources_bindings_vive_tracker_camera_json_len, false) != src_resources_bindings_vive_tracker_camera_json_len ||
lovrFilesystemWrite("bindings_vive_tracker_keyboard.json", (const char*) src_resources_bindings_vive_tracker_keyboard_json, src_resources_bindings_vive_tracker_keyboard_json_len, false) != src_resources_bindings_vive_tracker_keyboard_json_len
) {
VR_ShutdownInternal();
return false;
}
}
char path[LOVR_PATH_MAX];
snprintf(path, sizeof(path), "%s%cactions.json", lovrFilesystemGetSaveDirectory(), LOVR_PATH_SEP);
state.input->SetActionManifestPath(path);
state.input->GetActionSetHandle("/actions/lovr", &state.actionSet);
state.input->GetActionHandle("/actions/lovr/in/headPose", &state.poseActions[DEVICE_HEAD]);
state.input->GetActionHandle("/actions/lovr/in/leftHandPose", &state.poseActions[DEVICE_HAND_LEFT]);
state.input->GetActionHandle("/actions/lovr/in/rightHandPose", &state.poseActions[DEVICE_HAND_RIGHT]);
state.input->GetActionHandle("/actions/lovr/in/leftHandPoint", &state.poseActions[DEVICE_HAND_LEFT_POINT]);
state.input->GetActionHandle("/actions/lovr/in/rightHandPoint", &state.poseActions[DEVICE_HAND_RIGHT_POINT]);
state.input->GetActionHandle("/actions/lovr/in/leftElbowPose", &state.poseActions[DEVICE_ELBOW_LEFT]);
state.input->GetActionHandle("/actions/lovr/in/rightElbowPose", &state.poseActions[DEVICE_ELBOW_RIGHT]);
state.input->GetActionHandle("/actions/lovr/in/leftShoulderPose", &state.poseActions[DEVICE_SHOULDER_LEFT]);
state.input->GetActionHandle("/actions/lovr/in/rightShoulderPose", &state.poseActions[DEVICE_SHOULDER_RIGHT]);
state.input->GetActionHandle("/actions/lovr/in/chestPose", &state.poseActions[DEVICE_CHEST]);
state.input->GetActionHandle("/actions/lovr/in/waistPose", &state.poseActions[DEVICE_WAIST]);
state.input->GetActionHandle("/actions/lovr/in/leftKneePose", &state.poseActions[DEVICE_KNEE_LEFT]);
state.input->GetActionHandle("/actions/lovr/in/rightKneePose", &state.poseActions[DEVICE_KNEE_RIGHT]);
state.input->GetActionHandle("/actions/lovr/in/leftFootPose", &state.poseActions[DEVICE_FOOT_LEFT]);
state.input->GetActionHandle("/actions/lovr/in/rightFootPose", &state.poseActions[DEVICE_FOOT_RIGHT]);
state.input->GetActionHandle("/actions/lovr/in/cameraPose", &state.poseActions[DEVICE_CAMERA]);
state.input->GetActionHandle("/actions/lovr/in/keyboardPose", &state.poseActions[DEVICE_KEYBOARD]);
state.input->GetActionHandle("/actions/lovr/in/leftTriggerDown", &state.buttonActions[0][BUTTON_TRIGGER]);
state.input->GetActionHandle("/actions/lovr/in/leftThumbstickDown", &state.buttonActions[0][BUTTON_THUMBSTICK]);
state.input->GetActionHandle("/actions/lovr/in/leftTouchpadDown", &state.buttonActions[0][BUTTON_TOUCHPAD]);
state.input->GetActionHandle("/actions/lovr/in/leftGripDown", &state.buttonActions[0][BUTTON_GRIP]);
state.input->GetActionHandle("/actions/lovr/in/leftMenuDown", &state.buttonActions[0][BUTTON_MENU]);
state.input->GetActionHandle("/actions/lovr/in/leftADown", &state.buttonActions[0][BUTTON_A]);
state.input->GetActionHandle("/actions/lovr/in/leftBDown", &state.buttonActions[0][BUTTON_B]);
state.input->GetActionHandle("/actions/lovr/in/leftXDown", &state.buttonActions[0][BUTTON_X]);
state.input->GetActionHandle("/actions/lovr/in/leftYDown", &state.buttonActions[0][BUTTON_Y]);
state.input->GetActionHandle("/actions/lovr/in/rightTriggerDown", &state.buttonActions[1][BUTTON_TRIGGER]);
state.input->GetActionHandle("/actions/lovr/in/rightThumbstickDown", &state.buttonActions[1][BUTTON_THUMBSTICK]);
state.input->GetActionHandle("/actions/lovr/in/rightTouchpadDown", &state.buttonActions[1][BUTTON_TOUCHPAD]);
state.input->GetActionHandle("/actions/lovr/in/rightGripDown", &state.buttonActions[1][BUTTON_GRIP]);
state.input->GetActionHandle("/actions/lovr/in/rightMenuDown", &state.buttonActions[1][BUTTON_MENU]);
state.input->GetActionHandle("/actions/lovr/in/rightADown", &state.buttonActions[1][BUTTON_A]);
state.input->GetActionHandle("/actions/lovr/in/rightBDown", &state.buttonActions[1][BUTTON_B]);
state.input->GetActionHandle("/actions/lovr/in/rightXDown", &state.buttonActions[1][BUTTON_X]);
state.input->GetActionHandle("/actions/lovr/in/rightYDown", &state.buttonActions[1][BUTTON_Y]);
state.input->GetActionHandle("/actions/lovr/in/leftTriggerTouch", &state.touchActions[0][BUTTON_TRIGGER]);
state.input->GetActionHandle("/actions/lovr/in/leftThumbstickTouch", &state.touchActions[0][BUTTON_THUMBSTICK]);
state.input->GetActionHandle("/actions/lovr/in/leftTouchpadTouch", &state.touchActions[0][BUTTON_TOUCHPAD]);
state.input->GetActionHandle("/actions/lovr/in/leftGripTouch", &state.touchActions[0][BUTTON_GRIP]);
state.input->GetActionHandle("/actions/lovr/in/leftMenuTouch", &state.touchActions[0][BUTTON_MENU]);
state.input->GetActionHandle("/actions/lovr/in/leftATouch", &state.touchActions[0][BUTTON_A]);
state.input->GetActionHandle("/actions/lovr/in/leftBTouch", &state.touchActions[0][BUTTON_B]);
state.input->GetActionHandle("/actions/lovr/in/leftXTouch", &state.touchActions[0][BUTTON_X]);
state.input->GetActionHandle("/actions/lovr/in/leftYTouch", &state.touchActions[0][BUTTON_Y]);
state.input->GetActionHandle("/actions/lovr/in/rightTriggerTouch", &state.touchActions[1][BUTTON_TRIGGER]);
state.input->GetActionHandle("/actions/lovr/in/rightThumbstickTouch", &state.touchActions[1][BUTTON_THUMBSTICK]);
state.input->GetActionHandle("/actions/lovr/in/rightTouchpadTouch", &state.touchActions[1][BUTTON_TOUCHPAD]);
state.input->GetActionHandle("/actions/lovr/in/rightGripTouch", &state.touchActions[1][BUTTON_GRIP]);
state.input->GetActionHandle("/actions/lovr/in/rightMenuTouch", &state.touchActions[1][BUTTON_MENU]);
state.input->GetActionHandle("/actions/lovr/in/rightATouch", &state.touchActions[1][BUTTON_A]);
state.input->GetActionHandle("/actions/lovr/in/rightBTouch", &state.touchActions[1][BUTTON_B]);
state.input->GetActionHandle("/actions/lovr/in/rightXTouch", &state.touchActions[1][BUTTON_X]);
state.input->GetActionHandle("/actions/lovr/in/rightYTouch", &state.touchActions[1][BUTTON_Y]);
state.input->GetActionHandle("/actions/lovr/in/leftTriggerAxis", &state.axisActions[0][AXIS_TRIGGER]);
state.input->GetActionHandle("/actions/lovr/in/leftThumbstickAxis", &state.axisActions[0][AXIS_THUMBSTICK]);
state.input->GetActionHandle("/actions/lovr/in/leftTouchpadAxis", &state.axisActions[0][AXIS_TOUCHPAD]);
state.input->GetActionHandle("/actions/lovr/in/leftGripAxis", &state.axisActions[0][AXIS_GRIP]);
state.input->GetActionHandle("/actions/lovr/in/rightTriggerAxis", &state.axisActions[1][AXIS_TRIGGER]);
state.input->GetActionHandle("/actions/lovr/in/rightThumbstickAxis", &state.axisActions[1][AXIS_THUMBSTICK]);
state.input->GetActionHandle("/actions/lovr/in/rightTouchpadAxis", &state.axisActions[1][AXIS_TOUCHPAD]);
state.input->GetActionHandle("/actions/lovr/in/rightGripAxis", &state.axisActions[1][AXIS_GRIP]);
state.input->GetActionHandle("/actions/lovr/in/leftHandSkeleton", &state.skeletonActions[0]);
state.input->GetActionHandle("/actions/lovr/in/rightHandSkeleton", &state.skeletonActions[1]);
state.input->GetActionHandle("/actions/lovr/out/leftHandBZZ", &state.hapticActions[0]);
state.input->GetActionHandle("/actions/lovr/out/rightHandBZZ", &state.hapticActions[1]);
state.input->GetInputSourceHandle("/user/head", &state.inputSources[DEVICE_HEAD]);
state.input->GetInputSourceHandle("/user/hand/left", &state.inputSources[DEVICE_HAND_LEFT]);
state.input->GetInputSourceHandle("/user/hand/right", &state.inputSources[DEVICE_HAND_RIGHT]);
state.clipNear = 0.1f;
state.clipFar = 100.f;
state.supersample = supersample;
state.offset = state.compositor->GetTrackingSpace() == ETrackingUniverseOrigin_TrackingUniverseStanding ? 0. : offset;
state.msaa = msaa;
return true;
}
static void openvr_start(void) {
uint32_t width, height;
state.system->GetRecommendedRenderTargetSize(&width, &height);
width *= state.supersample;
height *= state.supersample;
CanvasFlags flags = { .depth = { true, false, FORMAT_D24S8 }, .stereo = true, .mipmaps = true, .msaa = state.msaa };
state.canvas = lovrCanvasCreate(width, height, flags);
Texture* texture = lovrTextureCreate(TEXTURE_2D, NULL, 0, true, true, state.msaa);
lovrTextureAllocate(texture, width * 2, height, 1, FORMAT_RGBA);
lovrTextureSetFilter(texture, lovrGraphicsGetDefaultFilter());
lovrCanvasSetAttachments(state.canvas, &(Attachment) { texture, 0, 0 }, 1);
lovrRelease(texture, lovrTextureDestroy);
os_window_set_vsync(0);
}
static void openvr_destroy(void) {
lovrRelease(state.canvas, lovrCanvasDestroy);
VR_ShutdownInternal();
free(state.mask);
memset(&state, 0, sizeof(state));
}
static bool openvr_getName(char* name, size_t length) {
ETrackedPropertyError error;
state.system->GetStringTrackedDeviceProperty(HEADSET, ETrackedDeviceProperty_Prop_ManufacturerName_String, name, (uint32_t) length, &error);
return error == ETrackedPropertyError_TrackedProp_Success;
}
static HeadsetOrigin openvr_getOriginType(void) {
switch (state.compositor->GetTrackingSpace()) {
case ETrackingUniverseOrigin_TrackingUniverseSeated: return ORIGIN_HEAD;
case ETrackingUniverseOrigin_TrackingUniverseStanding: return ORIGIN_FLOOR;
default: return ORIGIN_HEAD;
}
}
static void openvr_getDisplayDimensions(uint32_t* width, uint32_t* height) {
state.system->GetRecommendedRenderTargetSize(width, height);
}
static float openvr_getDisplayFrequency(void) {
return state.system->GetFloatTrackedDeviceProperty(HEADSET, ETrackedDeviceProperty_Prop_DisplayFrequency_Float, NULL);
}
static const float* openvr_getDisplayMask(uint32_t* count) {
struct HiddenAreaMesh_t hiddenAreaMesh = state.system->GetHiddenAreaMesh(EVREye_Eye_Left, EHiddenAreaMeshType_k_eHiddenAreaMesh_Standard);
if (hiddenAreaMesh.unTriangleCount == 0) {
*count = 0;
return NULL;
}
state.mask = realloc(state.mask, hiddenAreaMesh.unTriangleCount * 3 * 2 * sizeof(float));
lovrAssert(state.mask, "Out of memory");
for (uint32_t i = 0; i < 3 * hiddenAreaMesh.unTriangleCount; i++) {
state.mask[2 * i + 0] = hiddenAreaMesh.pVertexData[i].v[0];
state.mask[2 * i + 1] = hiddenAreaMesh.pVertexData[i].v[1];
}
*count = hiddenAreaMesh.unTriangleCount * 3 * 2;
return state.mask;
}
static double openvr_getDisplayTime(void) {
float secondsSinceVsync;
state.system->GetTimeSinceLastVsync(&secondsSinceVsync, NULL);
float frequency = openvr_getDisplayFrequency();
float frameDuration = 1.f / frequency;
float vsyncToPhotons = state.system->GetFloatTrackedDeviceProperty(HEADSET, ETrackedDeviceProperty_Prop_SecondsFromVsyncToPhotons_Float, NULL);
return os_get_time() + (double) (frameDuration - secondsSinceVsync + vsyncToPhotons);
}
static uint32_t openvr_getViewCount(void) {
return 2;
}
static bool openvr_getViewPose(uint32_t view, float* position, float* orientation) {
EVREye eye = view ? EVREye_Eye_Right : EVREye_Eye_Left;
float transform[16], offset[16];
mat4_fromMat34(transform, state.renderPoses[k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking.m);
mat4_mul(transform, mat4_fromMat34(offset, state.system->GetEyeToHeadTransform(eye).m));
mat4_getPosition(transform, position);
mat4_getOrientation(transform, orientation);
position[1] += state.offset;
return view < 2;
}
static bool openvr_getViewAngles(uint32_t view, float* left, float* right, float* up, float* down) {
EVREye eye = view ? EVREye_Eye_Right : EVREye_Eye_Left;
state.system->GetProjectionRaw(eye, left, right, up, down);
*left = atanf(*left);
*right = atanf(*right);
*up = atanf(*up);
*down = atanf(*down);
return view < 2;
}
static void openvr_getClipDistance(float* clipNear, float* clipFar) {
*clipNear = state.clipNear;
*clipFar = state.clipFar;
}
static void openvr_setClipDistance(float clipNear, float clipFar) {
state.clipNear = clipNear;
state.clipFar = clipFar;
}
static void openvr_getBoundsDimensions(float* width, float* depth) {
state.chaperone->GetPlayAreaSize(width, depth);
}
static const float* openvr_getBoundsGeometry(uint32_t* count) {
struct HmdQuad_t quad;
if (state.chaperone->GetPlayAreaRect(&quad)) {
for (int i = 0; i < 4; i++) {
state.boundsGeometry[4 * i + 0] = quad.vCorners[i].v[0];
state.boundsGeometry[4 * i + 1] = quad.vCorners[i].v[1];
state.boundsGeometry[4 * i + 2] = quad.vCorners[i].v[2];
}
*count = 16;
return state.boundsGeometry;
}
return NULL;
}
static bool openvr_getPose(Device device, vec3 position, quat orientation) {
float transform[16];
// Early exit for head pose
if (device == DEVICE_HEAD) {
mat4_fromMat34(transform, state.renderPoses[k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking.m);
transform[13] += state.offset;
mat4_getPosition(transform, position);
mat4_getOrientation(transform, orientation);
return state.renderPoses[k_unTrackedDeviceIndex_Hmd].bPoseIsValid;
}
// Lighthouse devices use the old tracked device index API
if (device >= DEVICE_BEACON_1 && device <= DEVICE_BEACON_4) {
TrackedDeviceIndex_t devices[4];
ETrackedDeviceClass class = ETrackedDeviceClass_TrackedDeviceClass_TrackingReference;
uint32_t count = state.system->GetSortedTrackedDeviceIndicesOfClass(class, devices, 4, 0);
uint32_t index = device - DEVICE_BEACON_1;
if (index >= count) return false;
TrackedDevicePose_t* pose = &state.renderPoses[devices[index]];
mat4_fromMat34(transform, pose->mDeviceToAbsoluteTracking.m);
transform[13] += state.offset;
mat4_getPosition(transform, position);
mat4_getOrientation(transform, orientation);
return pose->bPoseIsValid;
}
// Generic device
if (state.poseActions[device]) {
InputPoseActionData_t action;
state.input->GetPoseActionDataForNextFrame(state.poseActions[device], state.compositor->GetTrackingSpace(), &action, sizeof(action), 0);
mat4_fromMat34(transform, action.pose.mDeviceToAbsoluteTracking.m);
transform[13] += state.offset;
mat4_getPosition(transform, position);
mat4_getOrientation(transform, orientation);
return action.pose.bPoseIsValid;
}
return false;
}
static bool openvr_getVelocity(Device device, vec3 velocity, vec3 angularVelocity) {
InputPoseActionData_t action;
TrackedDevicePose_t* pose;
if (device == DEVICE_HEAD) {
pose = &state.renderPoses[k_unTrackedDeviceIndex_Hmd];
} else if (state.poseActions[device]) {
state.input->GetPoseActionDataForNextFrame(state.poseActions[device], state.compositor->GetTrackingSpace(), &action, sizeof(action), 0);
pose = &action.pose;
} else {
return false;
}
vec3_init(velocity, pose->vVelocity.v);
vec3_init(angularVelocity, pose->vAngularVelocity.v);
return pose->bPoseIsValid;
}
static bool openvr_isDown(Device device, DeviceButton button, bool* down, bool* changed) {
if (device != DEVICE_HAND_LEFT && device != DEVICE_HAND_RIGHT) {
return false;
}
InputDigitalActionData_t action;
state.input->GetDigitalActionData(state.buttonActions[device - DEVICE_HAND_LEFT][button], &action, sizeof(action), 0);
*down = action.bState;
*changed = action.bChanged;
return action.bActive;
}
static bool openvr_isTouched(Device device, DeviceButton button, bool* touched) {
if (device != DEVICE_HAND_LEFT && device != DEVICE_HAND_RIGHT) {
return false;
}
InputDigitalActionData_t action;
state.input->GetDigitalActionData(state.touchActions[device - DEVICE_HAND_LEFT][button], &action, sizeof(action), 0);
*touched = action.bState;
return action.bActive;
}
static bool openvr_getAxis(Device device, DeviceAxis axis, vec3 value) {
if (device != DEVICE_HAND_LEFT && device != DEVICE_HAND_RIGHT) {
return false;
}
InputAnalogActionData_t action;
state.input->GetAnalogActionData(state.axisActions[device - DEVICE_HAND_LEFT][axis], &action, sizeof(action), 0);
vec3_set(value, action.x, action.y, action.z);
return action.bActive;
}
static bool openvr_getSkeleton(Device device, float* poses) {
if (device != DEVICE_HAND_LEFT && device != DEVICE_HAND_RIGHT) {
return false;
}
// Bone transforms are relative to the hand instead of the origin, so get the hand pose first
InputPoseActionData_t handPose;
state.input->GetPoseActionDataForNextFrame(state.poseActions[device], state.compositor->GetTrackingSpace(), &handPose, sizeof(handPose), 0);
if (!handPose.pose.bPoseIsValid) {
return false;
}
float transform[16], position[4], orientation[4];
mat4_fromMat34(transform, handPose.pose.mDeviceToAbsoluteTracking.m);
transform[13] += state.offset;
mat4_getPosition(transform, position);
mat4_getOrientation(transform, orientation);
InputSkeletalActionData_t info;
VRActionHandle_t action = state.skeletonActions[device - DEVICE_HAND_LEFT];
EVRInputError error = state.input->GetSkeletalActionData(action, &info, sizeof(info));
if (error || !info.bActive) {
return false;
}
VRBoneTransform_t bones[32];
uint32_t boneCount;
error = state.input->GetBoneCount(action, &boneCount);
if (error || boneCount > sizeof(bones) / sizeof(bones[0])) {
return false;
}
EVRSkeletalTransformSpace space = EVRSkeletalTransformSpace_VRSkeletalTransformSpace_Model;
EVRSkeletalMotionRange motionRange = EVRSkeletalMotionRange_VRSkeletalMotionRange_WithController;
error = state.input->GetSkeletalBoneData(action, space, motionRange, bones, boneCount);
if (error) {
printf("No bone data %d\n", error);
return false;
}
// Copy SteamVR bone transform to output (indices match up)
// Swap x/w (HmdQuaternionf_t has w first)
// Premultiply by hand pose
float* pose = poses;
// SteamVR has a root joint instead of a palm joint, we zero out the root joint so it is the same
// as the regular hand pose
memset(&bones[0], 0, sizeof(bones[0]));
bones[0].orientation.w = 1.f;
for (uint32_t i = 1; i < HAND_JOINT_COUNT; i++) {
memcpy(pose, &bones[i].position, 8 * sizeof(float));
float w = pose[4];
pose[4] = pose[7];
pose[7] = w;
quat_rotate(orientation, pose);
vec3_add(pose, position);
quat_mul(pose + 4, orientation, pose + 4);
pose += 8;
}
return true;
}
static bool openvr_vibrate(Device device, float strength, float duration, float frequency) {
if (duration <= 0.f || (device != DEVICE_HAND_LEFT && device != DEVICE_HAND_RIGHT)) return false;
if (frequency <= 0.f) {
frequency = 1.f;
}
state.input->TriggerHapticVibrationAction(state.hapticActions[device - DEVICE_HAND_LEFT], 0.f, duration, frequency, strength, 0);
return true;
}
static bool loadRenderModel(char* name, RenderModel_t** model, RenderModel_TextureMap_t** texture) {
loadModel:
switch (state.renderModels->LoadRenderModel_Async(name, model)) {
case EVRRenderModelError_VRRenderModelError_Loading: os_sleep(.001); goto loadModel;
case EVRRenderModelError_VRRenderModelError_None: break;
default: return false;
}
loadTexture:
switch (state.renderModels->LoadTexture_Async((*model)->diffuseTextureId, texture)) {
case EVRRenderModelError_VRRenderModelError_Loading: os_sleep(.001); goto loadTexture;
case EVRRenderModelError_VRRenderModelError_None: break;
default: state.renderModels->FreeRenderModel(*model); return false;
}
return true;
}
static ModelData* openvr_newModelData(Device device, bool animated) {
TrackedDeviceIndex_t index = getDeviceIndex(device);
if (index == INVALID_DEVICE) return NULL;
RenderModel_t* renderModel = NULL;
RenderModel_TextureMap_t* renderModelTexture = NULL;
RenderModel_t** renderModels = NULL;
RenderModel_TextureMap_t** renderModelTextures = NULL;
uint32_t modelCount = 0;
char renderModelName[1024];
ETrackedDeviceProperty renderModelNameProperty = ETrackedDeviceProperty_Prop_RenderModelName_String;
state.system->GetStringTrackedDeviceProperty(index, renderModelNameProperty, renderModelName, 1024, NULL);
char* names = NULL;
size_t namesSize = 0;
uint32_t charCount = 0;
if (!animated) {
modelCount = 1;
renderModels = &renderModel;
renderModelTextures = &renderModelTexture;
if (!loadRenderModel(renderModelName, &renderModel, &renderModelTexture)) {
return NULL;
}
} else {
uint32_t componentCount = state.renderModels->GetComponentCount(renderModelName);
renderModels = malloc(componentCount * sizeof(*renderModels));
renderModelTextures = malloc(componentCount * sizeof(*renderModelTextures));
lovrAssert(renderModels && renderModelTextures, "Out of memory");
for (uint32_t i = 0; i < componentCount; i++) {
if (namesSize < charCount + 256) {
namesSize += 256;
names = realloc(names, namesSize);
lovrAssert(names, "Out of memory");
}
char componentModel[1024];
uint32_t size = state.renderModels->GetComponentName(renderModelName, i, names + charCount, 256);
if (!state.renderModels->GetComponentRenderModelName(renderModelName, names + charCount, componentModel, sizeof(componentModel))) {
continue;
}
// Sadly this loads the components serially...
if (!loadRenderModel(componentModel, &renderModels[modelCount], &renderModelTextures[modelCount])) {
for (uint32_t j = 0; modelCount > 0 && j < modelCount; j++) {
state.renderModels->FreeRenderModel(renderModels[j]);
state.renderModels->FreeTexture(renderModelTextures[j]);
}
free(renderModels);
free(renderModelTextures);
return NULL;
}
charCount += size;
modelCount++;
}
}
ModelData* model = calloc(1, sizeof(ModelData));
lovrAssert(model, "Out of memory");
model->ref = 1;
model->blobCount = 2;
model->nodeCount = animated ? (1 + modelCount) : 1;
model->bufferCount = 2 * modelCount;
model->attributeCount = 4 * modelCount;
model->imageCount = modelCount;
model->materialCount = modelCount;
model->primitiveCount = modelCount;
model->childCount = animated ? modelCount : 0;
model->charCount = charCount;
lovrModelDataAllocate(model);
memcpy(model->chars, names, charCount);
free(names);
uint32_t totalVertexCount = 0;
uint32_t totalIndexCount = 0;
for (uint32_t i = 0; i < modelCount; i++) {
lovrAssert(renderModels[i]->unTriangleCount > 0, "Unsupported OpenVR model: no index buffer (please report this)");
totalVertexCount += renderModels[i]->unVertexCount;
totalIndexCount += renderModels[i]->unTriangleCount * 3;
}
size_t vertexSize = sizeof(RenderModel_Vertex_t);
float* vertices = malloc(totalVertexCount * vertexSize);
uint16_t* indices = malloc(totalIndexCount * sizeof(uint16_t));
lovrAssert(vertices && indices, "Out of memory");
model->blobs[0] = lovrBlobCreate(vertices, totalVertexCount * vertexSize, "OpenVR Model Vertices");
model->blobs[1] = lovrBlobCreate(indices, totalIndexCount * sizeof(uint16_t), "OpenVR Model Indices");
char* name = model->chars;
for (uint32_t i = 0; i < modelCount; i++) {
uint32_t vertexCount = renderModels[i]->unVertexCount;
uint32_t indexCount = renderModels[i]->unTriangleCount * 3;
memcpy(vertices, renderModels[i]->rVertexData, vertexCount * vertexSize);
memcpy(indices, renderModels[i]->rIndexData, indexCount * sizeof(uint16_t));
model->buffers[2 * i + 0] = (ModelBuffer) {
.blob = 0,
.size = vertexCount * vertexSize,
.stride = vertexSize,
.data = (char*) vertices
};
model->buffers[2 * i + 1] = (ModelBuffer) {
.blob = 1,
.size = indexCount * sizeof(uint16_t),
.stride = sizeof(uint16_t),
.data = (char*) indices
};
vertices += vertexCount * vertexSize / sizeof(float);
indices += indexCount;
model->attributes[4 * i + 0] = (ModelAttribute) {
.buffer = 2 * i,
.offset = offsetof(RenderModel_Vertex_t, vPosition),
.count = vertexCount,
.type = F32,
.components = 3
};
model->attributes[4 * i + 1] = (ModelAttribute) {
.buffer = 2 * i,
.offset = offsetof(RenderModel_Vertex_t, vNormal),
.count = vertexCount,
.type = F32,
.components = 3
};
model->attributes[4 * i + 2] = (ModelAttribute) {
.buffer = 2 * i,
.offset = offsetof(RenderModel_Vertex_t, rfTextureCoord),
.count = vertexCount,
.type = F32,
.components = 2
};
model->attributes[4 * i + 3] = (ModelAttribute) {
.buffer = 2 * i + 1,
.offset = 0,
.count = indexCount,
.type = U16,
.components = 1
};
RenderModel_TextureMap_t* texture = renderModelTextures[i];
model->images[i] = lovrImageCreate(texture->unWidth, texture->unHeight, NULL, 0, FORMAT_RGBA);
memcpy(model->images[i]->blob->data, texture->rubTextureMapData, texture->unWidth * texture->unHeight * 4);
model->materials[i] = (ModelMaterial) {
.colors[COLOR_DIFFUSE] = { 1.f, 1.f, 1.f, 1.f },
.images[TEXTURE_DIFFUSE] = i,
.filters[TEXTURE_DIFFUSE] = lovrGraphicsGetDefaultFilter()
};
model->primitives[i] = (ModelPrimitive) {
.mode = DRAW_TRIANGLES,
.attributes = {
[ATTR_POSITION] = &model->attributes[4 * i + 0],
[ATTR_NORMAL] = &model->attributes[4 * i + 1],
[ATTR_TEXCOORD] = &model->attributes[4 * i + 2]
},
.indices = &model->attributes[4 * i + 3],
.material = i
};
model->nodes[i] = (ModelNode) {
.name = name,
.transform.matrix = MAT4_IDENTITY,
.primitiveIndex = i,
.primitiveCount = 1,
.skin = ~0u,
.matrix = true
};
name = strchr(name, '\0') + 1;
}
for (uint32_t i = 0; i < modelCount; i++) {
state.renderModels->FreeRenderModel(renderModels[i]);
state.renderModels->FreeTexture(renderModelTextures[i]);
}
// Root node
if (animated) {
for (uint32_t i = 0; i < modelCount; i++) {
model->children[i] = i;
}
model->rootNode = modelCount;
model->nodes[model->rootNode] = (ModelNode) {
.transform.matrix = MAT4_IDENTITY,
.matrix = true,
.childCount = modelCount,
.children = model->children,
.skin = ~0u
};
free(renderModels);
free(renderModelTextures);
}
return model;
}
static bool openvr_animate(Device device, Model* model) {
if (device != DEVICE_HAND_LEFT && device != DEVICE_HAND_RIGHT) {
return false;
}
TrackedDeviceIndex_t index = getDeviceIndex(device);
if (index == INVALID_DEVICE) {
return false;
}
char renderModelName[1024];
ETrackedDeviceProperty renderModelNameProperty = ETrackedDeviceProperty_Prop_RenderModelName_String;
state.system->GetStringTrackedDeviceProperty(index, renderModelNameProperty, renderModelName, 1024, NULL);
bool success = false;
ModelData* modelData = lovrModelGetModelData(model);
VRInputValueHandle_t inputSource = state.inputSources[device];
for (uint32_t i = 0; i < modelData->nodeCount; i++) {
ModelNode* node = &modelData->nodes[i];
if (!node->name || !state.renderModels->RenderModelHasComponent(renderModelName, (char*) node->name)) {
continue;
}
RenderModel_ComponentState_t componentState;
if (!state.renderModels->GetComponentStateForDevicePath(renderModelName, (char*) node->name, inputSource, NULL, &componentState)) {
continue;
}
float transform[16], position[4], orientation[4];
mat4_fromMat34(transform, componentState.mTrackingToComponentRenderModel.m);
mat4_getPosition(transform, position);
mat4_getOrientation(transform, orientation);
if (!(componentState.uProperties & EVRComponentProperty_VRComponentProperty_IsVisible)) {
vec3_set(position, 1e10, 1e10, 1e10); // Hide the node somehow (FIXME)
}
lovrModelPose(model, i, position, orientation, 1.f);
success = true;
}
return success;
}
static void openvr_renderTo(void (*callback)(void*), void* userdata) {
float head[16];
mat4_fromMat34(head, state.renderPoses[k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking.m);
for (int i = 0; i < 2; i++) {
float matrix[16], eye[16];
EVREye vrEye = (i == 0) ? EVREye_Eye_Left : EVREye_Eye_Right;
mat4_init(matrix, head);
mat4_mul(matrix, mat4_fromMat34(eye, state.system->GetEyeToHeadTransform(vrEye).m));
mat4_invert(matrix);
lovrGraphicsSetViewMatrix(i, matrix);
mat4_fromMat44(matrix, state.system->GetProjectionMatrix(vrEye, state.clipNear, state.clipFar).m);
lovrGraphicsSetProjection(i, matrix);
}
lovrGraphicsSetBackbuffer(state.canvas, true, true);
callback(userdata);
lovrGraphicsSetBackbuffer(NULL, false, false);
// Submit
const Attachment* attachments = lovrCanvasGetAttachments(state.canvas, NULL);
ptrdiff_t id = lovrTextureGetId(attachments[0].texture);
Texture_t eyeTexture = { (void*) id, ETextureType_TextureType_OpenGL, EColorSpace_ColorSpace_Linear };
VRTextureBounds_t left = { 0.f, 0.f, .5f, 1.f };
VRTextureBounds_t right = { .5f, 0.f, 1.f, 1.f };
state.compositor->Submit(EVREye_Eye_Left, &eyeTexture, &left, EVRSubmitFlags_Submit_Default);
state.compositor->Submit(EVREye_Eye_Right, &eyeTexture, &right, EVRSubmitFlags_Submit_Default);
lovrGpuDirtyTexture();
}
static Texture* openvr_getMirrorTexture(void) {
return lovrCanvasGetAttachments(state.canvas, NULL)[0].texture;
}
static void openvr_update(float dt) {
state.compositor->WaitGetPoses(state.renderPoses, sizeof(state.renderPoses) / sizeof(state.renderPoses[0]), NULL, 0);
VRActiveActionSet_t activeActionSet = { .ulActionSet = state.actionSet };
state.input->UpdateActionState(&activeActionSet, sizeof(activeActionSet), 1);
struct VREvent_t vrEvent;
while (state.system->PollNextEvent(&vrEvent, sizeof(vrEvent))) {
switch (vrEvent.eventType) {
case EVREventType_VREvent_InputFocusCaptured:
case EVREventType_VREvent_InputFocusReleased: {
bool isFocused = vrEvent.eventType == EVREventType_VREvent_InputFocusReleased;
lovrEventPush((Event) { .type = EVENT_FOCUS, .data.boolean = { isFocused } });
break;
}
case EVREventType_VREvent_Quit:
lovrEventPush((Event) { .type = EVENT_QUIT, .data.quit = { .exitCode = 0 } });
break;
default: break;
}
}
}
HeadsetInterface lovrHeadsetOpenVRDriver = {
.driverType = DRIVER_OPENVR,
.init = openvr_init,
.start = openvr_start,
.destroy = openvr_destroy,
.getName = openvr_getName,
.getOriginType = openvr_getOriginType,
.getDisplayDimensions = openvr_getDisplayDimensions,
.getDisplayFrequency = openvr_getDisplayFrequency,
.getDisplayMask = openvr_getDisplayMask,
.getDisplayTime = openvr_getDisplayTime,
.getViewCount = openvr_getViewCount,
.getViewPose = openvr_getViewPose,
.getViewAngles = openvr_getViewAngles,
.getClipDistance = openvr_getClipDistance,
.setClipDistance = openvr_setClipDistance,
.getBoundsDimensions = openvr_getBoundsDimensions,
.getBoundsGeometry = openvr_getBoundsGeometry,
.getPose = openvr_getPose,
.getVelocity = openvr_getVelocity,
.isDown = openvr_isDown,
.isTouched = openvr_isTouched,
.getAxis = openvr_getAxis,
.getSkeleton = openvr_getSkeleton,
.vibrate = openvr_vibrate,
.newModelData = openvr_newModelData,
.animate = openvr_animate,
.renderTo = openvr_renderTo,
.getMirrorTexture = openvr_getMirrorTexture,
.update = openvr_update
};

View File

@ -1,134 +0,0 @@
{
"action_sets" : [
{ "name" : "/actions/lovr", "usage" : "leftright" }
],
"actions" : [
{ "name" : "/actions/lovr/in/leftHandPose", "type" : "pose" },
{ "name" : "/actions/lovr/in/rightHandPose", "type" : "pose" },
{ "name" : "/actions/lovr/in/leftHandPoint", "type" : "pose" },
{ "name" : "/actions/lovr/in/rightHandPoint", "type" : "pose" },
{ "name" : "/actions/lovr/in/leftElbowPose", "type" : "pose" },
{ "name" : "/actions/lovr/in/rightElbowPose", "type" : "pose" },
{ "name" : "/actions/lovr/in/leftShoulderPose", "type" : "pose" },
{ "name" : "/actions/lovr/in/rightShoulderPose", "type" : "pose" },
{ "name" : "/actions/lovr/in/chestPose", "type" : "pose" },
{ "name" : "/actions/lovr/in/waistPose", "type" : "pose" },
{ "name" : "/actions/lovr/in/leftKneePose", "type" : "pose" },
{ "name" : "/actions/lovr/in/rightKneePose", "type" : "pose" },
{ "name" : "/actions/lovr/in/leftFootPose", "type" : "pose" },
{ "name" : "/actions/lovr/in/rightFootPose", "type" : "pose" },
{ "name" : "/actions/lovr/in/camera", "type" : "pose" },
{ "name" : "/actions/lovr/in/keyboard", "type" : "pose" },
{ "name" : "/actions/lovr/in/leftTriggerDown", "type" : "boolean" },
{ "name" : "/actions/lovr/in/leftTriggerTouch", "type" : "boolean" },
{ "name" : "/actions/lovr/in/leftTriggerAxis", "type" : "vector1" },
{ "name" : "/actions/lovr/in/leftTouchpadDown", "type" : "boolean" },
{ "name" : "/actions/lovr/in/leftTouchpadTouch", "type" : "boolean" },
{ "name" : "/actions/lovr/in/leftTouchpadAxis", "type" : "vector2" },
{ "name" : "/actions/lovr/in/leftThumbstickDown", "type" : "boolean" },
{ "name" : "/actions/lovr/in/leftThumbstickTouch", "type" : "boolean" },
{ "name" : "/actions/lovr/in/leftThumbstickAxis", "type" : "vector2" },
{ "name" : "/actions/lovr/in/leftGripDown", "type" : "boolean" },
{ "name" : "/actions/lovr/in/leftGripTouch", "type" : "boolean" },
{ "name" : "/actions/lovr/in/leftGripAxis", "type" : "vector1" },
{ "name" : "/actions/lovr/in/leftMenuDown", "type" : "boolean" },
{ "name" : "/actions/lovr/in/leftMenuTouch", "type" : "boolean" },
{ "name" : "/actions/lovr/in/leftADown", "type" : "boolean" },
{ "name" : "/actions/lovr/in/leftATouch", "type" : "boolean" },
{ "name" : "/actions/lovr/in/leftBDown", "type" : "boolean" },
{ "name" : "/actions/lovr/in/leftBTouch", "type" : "boolean" },
{ "name" : "/actions/lovr/in/leftXDown", "type" : "boolean" },
{ "name" : "/actions/lovr/in/leftXTouch", "type" : "boolean" },
{ "name" : "/actions/lovr/in/leftYDown", "type" : "boolean" },
{ "name" : "/actions/lovr/in/leftYTouch", "type" : "boolean" },
{ "name" : "/actions/lovr/in/rightTriggerDown", "type" : "boolean" },
{ "name" : "/actions/lovr/in/rightTriggerTouch", "type" : "boolean" },
{ "name" : "/actions/lovr/in/rightTriggerAxis", "type" : "vector1" },
{ "name" : "/actions/lovr/in/rightTouchpadDown", "type" : "boolean" },
{ "name" : "/actions/lovr/in/rightTouchpadTouch", "type" : "boolean" },
{ "name" : "/actions/lovr/in/rightTouchpadAxis", "type" : "vector2" },
{ "name" : "/actions/lovr/in/rightThumbstickDown", "type" : "boolean" },
{ "name" : "/actions/lovr/in/rightThumbstickTouch", "type" : "boolean" },
{ "name" : "/actions/lovr/in/rightThumbstickAxis", "type" : "vector2" },
{ "name" : "/actions/lovr/in/rightGripDown", "type" : "boolean" },
{ "name" : "/actions/lovr/in/rightGripTouch", "type" : "boolean" },
{ "name" : "/actions/lovr/in/rightGripAxis", "type" : "vector1" },
{ "name" : "/actions/lovr/in/rightMenuDown", "type" : "boolean" },
{ "name" : "/actions/lovr/in/rightMenuTouch", "type" : "boolean" },
{ "name" : "/actions/lovr/in/rightADown", "type" : "boolean" },
{ "name" : "/actions/lovr/in/rightATouch", "type" : "boolean" },
{ "name" : "/actions/lovr/in/rightBDown", "type" : "boolean" },
{ "name" : "/actions/lovr/in/rightBTouch", "type" : "boolean" },
{ "name" : "/actions/lovr/in/rightXDown", "type" : "boolean" },
{ "name" : "/actions/lovr/in/rightXTouch", "type" : "boolean" },
{ "name" : "/actions/lovr/in/rightYDown", "type" : "boolean" },
{ "name" : "/actions/lovr/in/rightYTouch", "type" : "boolean" },
{ "name" : "/actions/lovr/in/leftHandSkeleton", "skeleton" : "/skeleton/hand/left", "type" : "skeleton" },
{ "name" : "/actions/lovr/in/rightHandSkeleton", "skeleton" : "/skeleton/hand/right", "type" : "skeleton" },
{ "name" : "/actions/lovr/out/leftHandBZZ", "type" : "vibration" },
{ "name" : "/actions/lovr/out/rightHandBZZ", "type" : "vibration" }
],
"default_bindings" : [
{ "binding_url" : "bindings_vive.json", "controller_type" : "vive_controller" },
{ "binding_url" : "bindings_knuckles.json", "controller_type" : "knuckles" },
{ "binding_url" : "bindings_touch.json", "controller_type" : "oculus_touch" },
{ "binding_url" : "bindings_holographic_controller.json", "controller_type" : "holographic_controller" }
],
"localization" : [
{
"/actions/lovr/in/leftHandPose": "Left Hand Pose",
"/actions/lovr/in/rightHandPose": "Right Hand Pose",
"/actions/lovr/in/leftHandPoint": "Left Hand Point",
"/actions/lovr/in/rightHandPoint": "Right Hand Point",
"/actions/lovr/in/leftTriggerDown": "Left Trigger Press",
"/actions/lovr/in/leftTriggerTouch": "Left Trigger Touch",
"/actions/lovr/in/leftTriggerAxis": "Left Trigger Axis",
"/actions/lovr/in/leftTouchpadDown": "Left Touchpad Press",
"/actions/lovr/in/leftTouchpadTouch": "Left Touchpad Touch",
"/actions/lovr/in/leftTouchpadAxis": "Left Touchpad Axis",
"/actions/lovr/in/leftThumbstickDown": "Left Thumbstick Press",
"/actions/lovr/in/leftThumbstickTouch": "Left Thumbstick Touch",
"/actions/lovr/in/leftThumbstickAxis": "Left Thumbstick Axis",
"/actions/lovr/in/leftGripDown": "Left Grip Press",
"/actions/lovr/in/leftGripTouch": "Left Grip Touch",
"/actions/lovr/in/leftGripAxis": "Left Grip Axis",
"/actions/lovr/in/leftMenuDown": "Left Menu Press",
"/actions/lovr/in/leftMenuTouch": "Left Menu Touch",
"/actions/lovr/in/leftADown": "Left A Press",
"/actions/lovr/in/leftATouch": "Left A Touch",
"/actions/lovr/in/leftBDown": "Left B Press",
"/actions/lovr/in/leftBTouch": "Left B Touch",
"/actions/lovr/in/leftXDown": "Left X Press",
"/actions/lovr/in/leftXTouch": "Left X Touch",
"/actions/lovr/in/leftYDown": "Left Y Press",
"/actions/lovr/in/leftYTouch": "Left Y Touch",
"/actions/lovr/in/rightTriggerDown": "Right Trigger Press",
"/actions/lovr/in/rightTriggerTouch": "Right Trigger Touch",
"/actions/lovr/in/rightTriggerAxis": "Right Trigger Axis",
"/actions/lovr/in/rightTouchpadDown": "Right Touchpad Press",
"/actions/lovr/in/rightTouchpadTouch": "Right Touchpad Touch",
"/actions/lovr/in/rightTouchpadAxis": "Right Touchpad Axis",
"/actions/lovr/in/rightThumbstickDown": "Right Thumbstick Press",
"/actions/lovr/in/rightThumbstickTouch": "Right Thumbstick Touch",
"/actions/lovr/in/rightThumbstickAxis": "Right Thumbstick Axis",
"/actions/lovr/in/rightGripDown": "Right Grip Press",
"/actions/lovr/in/rightGripTouch": "Right Grip Touch",
"/actions/lovr/in/rightGripAxis": "Right Grip Axis",
"/actions/lovr/in/rightMenuDown": "Right Menu Press",
"/actions/lovr/in/rightMenuTouch": "Right Menu Touch",
"/actions/lovr/in/rightADown": "Right A Press",
"/actions/lovr/in/rightATouch": "Right A Touch",
"/actions/lovr/in/rightBDown": "Right B Press",
"/actions/lovr/in/rightBTouch": "Right B Touch",
"/actions/lovr/in/rightXDown": "Right X Press",
"/actions/lovr/in/rightXTouch": "Right X Touch",
"/actions/lovr/in/rightYDown": "Right Y Press",
"/actions/lovr/in/rightYTouch": "Right Y Touch",
"/actions/lovr/in/leftHandSkeleton": "Left Hand Skeleton",
"/actions/lovr/in/rightHandSkeleton": "Right Hand Skeleton",
"/actions/lovr/out/leftHandBZZ": "Left Hand BZZ",
"/actions/lovr/out/rightHandBZZ": "Right Hand BZZ",
"language_tag" : "en"
}
]
}

View File

@ -1,105 +0,0 @@
{
"action_manifest_version" : 0,
"alias_info" : {},
"bindings" : {
"/actions/lovr" : {
"haptics" : [
{ "output" : "/actions/lovr/out/leftHandBZZ", "path" : "/user/hand/left/output/haptic" },
{ "output" : "/actions/lovr/out/rightHandBZZ", "path" : "/user/hand/right/output/haptic" }
],
"poses" : [
{ "output" : "/actions/lovr/in/leftHandPose", "path" : "/user/hand/left/pose/raw" },
{ "output" : "/actions/lovr/in/rightHandPose", "path" : "/user/hand/right/pose/raw" }
],
"skeleton" : [
{ "output" : "/actions/lovr/in/leftHandSkeleton", "path" : "/user/hand/left/input/skeleton/left" },
{ "output" : "/actions/lovr/in/rightHandSkeleton", "path" : "/user/hand/right/input/skeleton/right" }
],
"sources" : [
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/rightTriggerDown" },
"pull" : { "output" : "/actions/lovr/in/rightTriggerAxis" }
},
"mode" : "trigger",
"path" : "/user/hand/right/input/trigger"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/rightGripDown" }
},
"mode" : "button",
"path" : "/user/hand/right/input/grip"
},
{
"inputs" : {
"position" : { "output" : "/actions/lovr/in/rightThumbstickAxis" },
"click" : { "output" : "/actions/lovr/in/rightThumbstickDown" }
},
"mode" : "joystick",
"path" : "/user/hand/right/input/joystick"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/rightTouchpadDown" },
"position" : { "output" : "/actions/lovr/in/rightTouchpadAxis" },
"touch" : { "output" : "/actions/lovr/in/rightTouchpadTouch" }
},
"mode" : "trackpad",
"path" : "/user/hand/right/input/trackpad"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/rightMenuDown" }
},
"mode" : "button",
"path" : "/user/hand/right/input/application_menu"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/leftTriggerDown" },
"pull" : { "output" : "/actions/lovr/in/leftTriggerAxis" }
},
"mode" : "trigger",
"path" : "/user/hand/left/input/trigger"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/leftGripDown" }
},
"mode" : "button",
"path" : "/user/hand/left/input/grip"
},
{
"inputs" : {
"position" : { "output" : "/actions/lovr/in/leftThumbstickAxis" },
"click" : { "output" : "/actions/lovr/in/leftThumbstickDown" }
},
"mode" : "joystick",
"path" : "/user/hand/left/input/joystick"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/leftTouchpadDown" },
"position" : { "output" : "/actions/lovr/in/leftTouchpadAxis" },
"touch" : { "output" : "/actions/lovr/in/leftTouchpadTouch" }
},
"mode" : "trackpad",
"path" : "/user/hand/left/input/trackpad"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/leftMenuDown" }
},
"mode" : "button",
"path" : "/user/hand/left/input/application_menu"
}
]
}
},
"controller_type" : "holographic_controller",
"description" : "",
"name" : "Windows Mixed Reality Controller Bindings",
"options" : {},
"simulated_actions" : []
}

View File

@ -1,169 +0,0 @@
{
"action_manifest_version" : 0,
"alias_info" : {},
"bindings" : {
"/actions/lovr" : {
"haptics" : [
{ "output" : "/actions/lovr/out/leftHandBZZ", "path" : "/user/hand/left/output/haptic" },
{ "output" : "/actions/lovr/out/rightHandBZZ", "path" : "/user/hand/right/output/haptic" }
],
"poses" : [
{ "output" : "/actions/lovr/in/leftHandPose", "path" : "/user/hand/left/pose/raw" },
{ "output" : "/actions/lovr/in/rightHandPose", "path" : "/user/hand/right/pose/raw" },
{ "output" : "/actions/lovr/in/leftHandPoint", "path" : "/user/hand/left/pose/tip" },
{ "output" : "/actions/lovr/in/rightHandPoint", "path" : "/user/hand/right/pose/tip" }
],
"skeleton" : [
{ "output" : "/actions/lovr/in/leftHandSkeleton", "path" : "/user/hand/left/input/skeleton/left" },
{ "output" : "/actions/lovr/in/rightHandSkeleton", "path" : "/user/hand/right/input/skeleton/right" }
],
"sources" : [
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/leftTriggerDown" },
"pull" : { "output" : "/actions/lovr/in/leftTriggerAxis" },
"touch" : { "output" : "/actions/lovr/in/leftTriggerTouch" }
},
"mode" : "trigger",
"path" : "/user/hand/left/input/trigger"
},
{
"inputs" : {
"position" : { "output" : "/actions/lovr/in/leftTouchpadAxis" },
"touch" : { "output" : "/actions/lovr/in/leftTouchpadTouch" }
},
"mode" : "trackpad",
"path" : "/user/hand/left/input/trackpad"
},
{
"inputs" : {
"touch" : { "output" : "/actions/lovr/in/leftGripTouch" }
},
"mode" : "trigger",
"path" : "/user/hand/left/input/grip"
},
{
"inputs" : {
"force" : { "output" : "/actions/lovr/in/leftGripAxis" }
},
"mode" : "force_sensor",
"path" : "/user/hand/left/input/grip"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/rightTriggerDown" },
"pull" : { "output" : "/actions/lovr/in/rightTriggerAxis" },
"touch" : { "output" : "/actions/lovr/in/rightTriggerTouch" }
},
"mode" : "trigger",
"path" : "/user/hand/right/input/trigger"
},
{
"inputs" : {
"position" : { "output" : "/actions/lovr/in/rightTouchpadAxis" },
"touch" : { "output" : "/actions/lovr/in/rightTouchpadTouch" }
},
"mode" : "trackpad",
"path" : "/user/hand/right/input/trackpad"
},
{
"inputs" : {
"touch" : { "output" : "/actions/lovr/in/rightGripTouch" }
},
"mode" : "trigger",
"path" : "/user/hand/right/input/grip"
},
{
"inputs" : {
"force" : { "output" : "/actions/lovr/in/rightGripAxis" }
},
"mode" : "force_sensor",
"path" : "/user/hand/right/input/grip"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/leftThumbstickDown" },
"position" : { "output" : "/actions/lovr/in/leftThumbstickAxis" },
"touch" : { "output" : "/actions/lovr/in/leftThumbstickTouch" }
},
"mode" : "joystick",
"path" : "/user/hand/left/input/thumbstick"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/leftBDown" },
"touch" : { "output" : "/actions/lovr/in/leftBTouch" }
},
"mode" : "button",
"path" : "/user/hand/left/input/b"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/leftADown" },
"touch" : { "output" : "/actions/lovr/in/leftATouch" }
},
"mode" : "button",
"path" : "/user/hand/left/input/a"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/rightThumbstickDown" },
"position" : { "output" : "/actions/lovr/in/rightThumbstickAxis" },
"touch" : { "output" : "/actions/lovr/in/rightThumbstickTouch" }
},
"mode" : "joystick",
"path" : "/user/hand/right/input/thumbstick"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/rightBDown" },
"touch" : { "output" : "/actions/lovr/in/rightBTouch" }
},
"mode" : "button",
"path" : "/user/hand/right/input/b"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/rightADown" },
"touch" : { "output" : "/actions/lovr/in/rightATouch" }
},
"mode" : "button",
"path" : "/user/hand/right/input/a"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/leftTouchpadDown" }
},
"mode" : "button",
"path" : "/user/hand/left/input/trackpad"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/rightTouchpadDown" }
},
"mode" : "button",
"path" : "/user/hand/right/input/trackpad"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/leftGripDown" }
},
"mode" : "button",
"path" : "/user/hand/left/input/grip"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/rightGripDown" }
},
"mode" : "button",
"path" : "/user/hand/right/input/grip"
}
]
}
},
"controller_type" : "knuckles",
"description" : "",
"name" : "Index Controller Bindings",
"options" : {},
"simulated_actions" : []
}

View File

@ -1,116 +0,0 @@
{
"action_manifest_version" : 0,
"alias_info" : {},
"app_key" : "system.generated.lovr.exe",
"bindings" : {
"/actions/lovr" : {
"haptics" : [
{ "output" : "/actions/lovr/out/leftHandBZZ", "path" : "/user/hand/left/output/haptic" },
{ "output" : "/actions/lovr/out/rightHandBZZ", "path" : "/user/hand/right/output/haptic" }
],
"poses" : [
{ "output" : "/actions/lovr/in/leftHandPose", "path" : "/user/hand/left/pose/raw" },
{ "output" : "/actions/lovr/in/rightHandPose", "path" : "/user/hand/right/pose/raw" },
{ "output" : "/actions/lovr/in/leftHandPoint", "path" : "/user/hand/left/pose/tip" },
{ "output" : "/actions/lovr/in/rightHandPoint", "path" : "/user/hand/right/pose/tip" }
],
"skeleton" : [
{ "output" : "/actions/lovr/in/leftHandSkeleton", "path" : "/user/hand/left/input/skeleton/left" },
{ "output" : "/actions/lovr/in/rightHandSkeleton", "path" : "/user/hand/right/input/skeleton/right" }
],
"sources" : [
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/rightGripDown" },
"pull" : { "output" : "/actions/lovr/in/rightGripAxis" },
"touch" : { "output" : "/actions/lovr/in/rightGripTouch" }
},
"mode" : "trigger",
"path" : "/user/hand/right/input/grip"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/leftGripDown" },
"pull" : { "output" : "/actions/lovr/in/leftGripAxis" },
"touch" : { "output" : "/actions/lovr/in/leftGripTouch" }
},
"mode" : "trigger",
"path" : "/user/hand/left/input/grip"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/rightTriggerDown" },
"pull" : { "output" : "/actions/lovr/in/rightTriggerAxis" },
"touch" : { "output" : "/actions/lovr/in/rightTriggerTouch" }
},
"mode" : "trigger",
"path" : "/user/hand/right/input/trigger"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/rightThumbstickDown" },
"position" : { "output" : "/actions/lovr/in/rightThumbstickAxis" },
"touch" : { "output" : "/actions/lovr/in/rightThumbstickTouch" }
},
"mode" : "joystick",
"path" : "/user/hand/right/input/joystick"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/rightADown" },
"touch" : { "output" : "/actions/lovr/in/rightATouch" }
},
"mode" : "button",
"path" : "/user/hand/right/input/a"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/rightBDown" },
"touch" : { "output" : "/actions/lovr/in/rightBTouch" }
},
"mode" : "button",
"path" : "/user/hand/right/input/b"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/leftTriggerDown" },
"pull" : { "output" : "/actions/lovr/in/leftTriggerAxis" },
"touch" : { "output" : "/actions/lovr/in/leftTriggerTouch" }
},
"mode" : "trigger",
"path" : "/user/hand/left/input/trigger"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/leftXDown" },
"touch" : { "output" : "/actions/lovr/in/leftXTouch" }
},
"mode" : "button",
"path" : "/user/hand/left/input/x"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/leftYDown" },
"touch" : { "output" : "/actions/lovr/in/leftYTouch" }
},
"mode" : "button",
"path" : "/user/hand/left/input/y"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/leftThumbstickDown" },
"position" : { "output" : "/actions/lovr/in/leftThumbstickAxis" },
"touch" : { "output" : "/actions/lovr/in/leftThumbstickTouch" }
},
"mode" : "joystick",
"path" : "/user/hand/left/input/joystick"
}
]
}
},
"controller_type" : "oculus_touch",
"description" : "",
"name" : "Oculus Touch Bindings",
"options" : {},
"simulated_actions" : []
}

View File

@ -1,92 +0,0 @@
{
"action_manifest_version" : 0,
"alias_info" : {},
"app_key" : "system.generated.lovr.exe",
"bindings" : {
"/actions/lovr" : {
"haptics" : [
{ "output" : "/actions/lovr/out/leftHandBZZ", "path" : "/user/hand/left/output/haptic" },
{ "output" : "/actions/lovr/out/rightHandBZZ", "path" : "/user/hand/right/output/haptic" }
],
"poses" : [
{ "output" : "/actions/lovr/in/leftHandPose", "path" : "/user/hand/left/pose/raw" },
{ "output" : "/actions/lovr/in/rightHandPose", "path" : "/user/hand/right/pose/raw" },
{ "output" : "/actions/lovr/in/leftHandPoint", "path" : "/user/hand/left/pose/tip" },
{ "output" : "/actions/lovr/in/rightHandPoint", "path" : "/user/hand/right/pose/tip" }
],
"skeleton" : [
{ "output" : "/actions/lovr/in/leftHandSkeleton", "path" : "/user/hand/left/input/skeleton/left" },
{ "output" : "/actions/lovr/in/rightHandSkeleton", "path" : "/user/hand/right/input/skeleton/right" }
],
"sources" : [
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/leftGripDown" }
},
"mode" : "button",
"path" : "/user/hand/left/input/grip"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/leftMenuDown" }
},
"mode" : "button",
"path" : "/user/hand/left/input/application_menu"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/leftTriggerDown" },
"pull" : { "output" : "/actions/lovr/in/leftTriggerAxis" }
},
"mode" : "trigger",
"path" : "/user/hand/left/input/trigger"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/leftTouchpadDown" },
"position" : { "output" : "/actions/lovr/in/leftTouchpadAxis" },
"touch" : { "output" : "/actions/lovr/in/leftTouchpadTouch" }
},
"mode" : "trackpad",
"path" : "/user/hand/left/input/trackpad"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/rightGripDown" }
},
"mode" : "button",
"path" : "/user/hand/right/input/grip"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/rightMenuDown" }
},
"mode" : "button",
"path" : "/user/hand/right/input/application_menu"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/rightTriggerDown" },
"pull" : { "output" : "/actions/lovr/in/rightTriggerAxis" }
},
"mode" : "trigger",
"path" : "/user/hand/right/input/trigger"
},
{
"inputs" : {
"click" : { "output" : "/actions/lovr/in/rightTouchpadDown" },
"position" : { "output" : "/actions/lovr/in/rightTouchpadAxis" },
"touch" : { "output" : "/actions/lovr/in/rightTouchpadTouch" }
},
"mode" : "trackpad",
"path" : "/user/hand/right/input/trackpad"
}
]
}
},
"controller_type" : "vive_controller",
"description" : "",
"name" : "Vive Bindings",
"options" : {},
"simulated_actions" : []
}

View File

@ -1,16 +0,0 @@
{
"action_manifest_version" : 0,
"alias_info" : {},
"bindings" : {
"/actions/lovr" : {
"poses" : [
{ "output": "/actions/lovr/in/cameraPose", "path": "/user/camera/pose/raw" }
]
}
},
"controller_type" : "vive_tracker_camera",
"description" : "",
"name" : "Camera Vive Tracker Bindings",
"options" : {},
"simulated_actions" : []
}

View File

@ -1,16 +0,0 @@
{
"action_manifest_version" : 0,
"alias_info" : {},
"bindings" : {
"/actions/lovr" : {
"poses" : [
{ "output": "/actions/lovr/in/chestPose", "path": "/user/chest/pose/raw" }
]
}
},
"controller_type" : "vive_tracker_chest",
"description" : "",
"name" : "Chest Vive Tracker Bindings",
"options" : {},
"simulated_actions" : []
}

View File

@ -1,16 +0,0 @@
{
"action_manifest_version" : 0,
"alias_info" : {},
"bindings" : {
"/actions/lovr" : {
"poses" : [
{ "output": "/actions/lovr/in/keyboardPose", "path": "/user/keyboard/pose/raw" }
]
}
},
"controller_type" : "vive_tracker_keyboard",
"description" : "",
"name" : "Keyboard Vive Tracker Bindings",
"options" : {},
"simulated_actions" : []
}

View File

@ -1,16 +0,0 @@
{
"action_manifest_version" : 0,
"alias_info" : {},
"bindings" : {
"/actions/lovr" : {
"poses" : [
{ "output": "/actions/lovr/in/leftElbowPose", "path": "/user/elbow/left/pose/raw" }
]
}
},
"controller_type" : "vive_tracker_left_elbow",
"description" : "",
"name" : "Left Elbow Vive Tracker Bindings",
"options" : {},
"simulated_actions" : []
}

View File

@ -1,16 +0,0 @@
{
"action_manifest_version" : 0,
"alias_info" : {},
"bindings" : {
"/actions/lovr" : {
"poses" : [
{ "output": "/actions/lovr/in/leftFootPose", "path": "/user/foot/left/pose/raw" }
]
}
},
"controller_type" : "vive_tracker_left_foot",
"description" : "",
"name" : "Left Foot Vive Tracker Bindings",
"options" : {},
"simulated_actions" : []
}

View File

@ -1,16 +0,0 @@
{
"action_manifest_version" : 0,
"alias_info" : {},
"bindings" : {
"/actions/lovr" : {
"poses" : [
{ "output": "/actions/lovr/in/leftKneePose", "path": "/user/knee/left/pose/raw" }
]
}
},
"controller_type" : "vive_tracker_left_knee",
"description" : "",
"name" : "Left Knee Vive Tracker Bindings",
"options" : {},
"simulated_actions" : []
}

View File

@ -1,16 +0,0 @@
{
"action_manifest_version" : 0,
"alias_info" : {},
"bindings" : {
"/actions/lovr" : {
"poses" : [
{ "output": "/actions/lovr/in/leftShoulderPose", "path": "/user/shoulder/left/pose/raw" }
]
}
},
"controller_type" : "vive_tracker_left_shoulder",
"description" : "",
"name" : "Left Shoulder Vive Tracker Bindings",
"options" : {},
"simulated_actions" : []
}

View File

@ -1,16 +0,0 @@
{
"action_manifest_version" : 0,
"alias_info" : {},
"bindings" : {
"/actions/lovr" : {
"poses" : [
{ "output": "/actions/lovr/in/rightElbowPose", "path": "/user/elbow/right/pose/raw" }
]
}
},
"controller_type" : "vive_tracker_right_elbow",
"description" : "",
"name" : "Right Elbow Vive Tracker Bindings",
"options" : {},
"simulated_actions" : []
}

View File

@ -1,16 +0,0 @@
{
"action_manifest_version" : 0,
"alias_info" : {},
"bindings" : {
"/actions/lovr" : {
"poses" : [
{ "output": "/actions/lovr/in/rightFootPose", "path": "/user/foot/right/pose/raw" }
]
}
},
"controller_type" : "vive_tracker_right_foot",
"description" : "",
"name" : "Right Foot Vive Tracker Bindings",
"options" : {},
"simulated_actions" : []
}

View File

@ -1,16 +0,0 @@
{
"action_manifest_version" : 0,
"alias_info" : {},
"bindings" : {
"/actions/lovr" : {
"poses" : [
{ "output": "/actions/lovr/in/rightKneePose", "path": "/user/knee/right/pose/raw" }
]
}
},
"controller_type" : "vive_tracker_right_knee",
"description" : "",
"name" : "Right Knee Vive Tracker Bindings",
"options" : {},
"simulated_actions" : []
}

View File

@ -1,16 +0,0 @@
{
"action_manifest_version" : 0,
"alias_info" : {},
"bindings" : {
"/actions/lovr" : {
"poses" : [
{ "output": "/actions/lovr/in/rightShoulderPose", "path": "/user/shoulder/right/pose/raw" }
]
}
},
"controller_type" : "vive_tracker_right_shoulder",
"description" : "",
"name" : "Right Shoulder Vive Tracker Bindings",
"options" : {},
"simulated_actions" : []
}

View File

@ -1,16 +0,0 @@
{
"action_manifest_version" : 0,
"alias_info" : {},
"bindings" : {
"/actions/lovr" : {
"poses" : [
{ "output": "/actions/lovr/in/waistPose", "path": "/user/waist/pose/raw" }
]
}
},
"controller_type" : "vive_tracker_waist",
"description" : "",
"name" : "Waist Vive Tracker Bindings",
"options" : {},
"simulated_actions" : []
}

View File

@ -121,7 +121,7 @@ function lovr.boot()
debug = false
},
headset = {
drivers = { 'openxr', 'oculus', 'vrapi', 'pico', 'openvr', 'webxr', 'desktop' },
drivers = { 'openxr', 'oculus', 'vrapi', 'pico', 'webxr', 'desktop' },
supersample = false,
offset = 1.7,
msaa = 4,