mirror of https://github.com/bjornbytes/lovr.git
Add lovr.headset.isPassthroughEnabled and lovr.headset.setPassthroughEnabled;
This commit is contained in:
parent
5a27a0f819
commit
89edccbf4c
18
etc/webxr.js
18
etc/webxr.js
|
@ -182,6 +182,11 @@ var webxr = {
|
||||||
return 1; /* ORIGIN_FLOOR */
|
return 1; /* ORIGIN_FLOOR */
|
||||||
},
|
},
|
||||||
|
|
||||||
|
webxr_getDisplayDimensions: function(width, height) {
|
||||||
|
HEAPU32[width >> 2] = state.layer.framebufferWidth;
|
||||||
|
HEAPU32[height >> 2] = state.layer.framebufferHeight;
|
||||||
|
},
|
||||||
|
|
||||||
webxr_getDisplayTime: function() {
|
webxr_getDisplayTime: function() {
|
||||||
return state.displayTime / 1000.0;
|
return state.displayTime / 1000.0;
|
||||||
},
|
},
|
||||||
|
@ -190,11 +195,6 @@ var webxr = {
|
||||||
return (state.displayTime - state.lastDisplayTime) / 1000.0;
|
return (state.displayTime - state.lastDisplayTime) / 1000.0;
|
||||||
},
|
},
|
||||||
|
|
||||||
webxr_getDisplayDimensions: function(width, height) {
|
|
||||||
HEAPU32[width >> 2] = state.layer.framebufferWidth;
|
|
||||||
HEAPU32[height >> 2] = state.layer.framebufferHeight;
|
|
||||||
},
|
|
||||||
|
|
||||||
webxr_getDisplayFrequency: function() {
|
webxr_getDisplayFrequency: function() {
|
||||||
return 0.0;
|
return 0.0;
|
||||||
},
|
},
|
||||||
|
@ -411,6 +411,14 @@ var webxr = {
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
webxr_isPassthroughEnabled: function() {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
webxr_setPassthroughEnabled: function() {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
webxr_update: function() {
|
webxr_update: function() {
|
||||||
return (state.displayTime - state.lastDisplayTime) / 1000.0;
|
return (state.displayTime - state.lastDisplayTime) / 1000.0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -539,6 +539,18 @@ static int l_lovrHeadsetIsFocused(lua_State* L) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int l_lovrHeadsetIsPassthroughEnabled(lua_State* L) {
|
||||||
|
lua_pushboolean(L, lovrHeadsetInterface->isPassthroughEnabled());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_lovrHeadsetSetPassthroughEnabled(lua_State* L) {
|
||||||
|
bool enable = lua_toboolean(L, 1);
|
||||||
|
bool success = lovrHeadsetInterface->setPassthroughEnabled(enable);
|
||||||
|
lua_pushboolean(L, success);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int l_lovrHeadsetUpdate(lua_State* L) {
|
static int l_lovrHeadsetUpdate(lua_State* L) {
|
||||||
double dt = 0.;
|
double dt = 0.;
|
||||||
|
|
||||||
|
@ -620,6 +632,8 @@ static const luaL_Reg lovrHeadset[] = {
|
||||||
{ "getPass", l_lovrHeadsetGetPass },
|
{ "getPass", l_lovrHeadsetGetPass },
|
||||||
{ "submit", l_lovrHeadsetSubmit },
|
{ "submit", l_lovrHeadsetSubmit },
|
||||||
{ "isFocused", l_lovrHeadsetIsFocused },
|
{ "isFocused", l_lovrHeadsetIsFocused },
|
||||||
|
{ "isPassthroughEnabled", l_lovrHeadsetIsPassthroughEnabled },
|
||||||
|
{ "setPassthroughEnabled", l_lovrHeadsetSetPassthroughEnabled },
|
||||||
{ "update", l_lovrHeadsetUpdate },
|
{ "update", l_lovrHeadsetUpdate },
|
||||||
{ "getTime", l_lovrHeadsetGetTime },
|
{ "getTime", l_lovrHeadsetGetTime },
|
||||||
{ "getDeltaTime", l_lovrHeadsetGetDeltaTime },
|
{ "getDeltaTime", l_lovrHeadsetGetDeltaTime },
|
||||||
|
|
|
@ -155,6 +155,8 @@ typedef struct HeadsetInterface {
|
||||||
struct Pass* (*getPass)(void);
|
struct Pass* (*getPass)(void);
|
||||||
void (*submit)(void);
|
void (*submit)(void);
|
||||||
bool (*isFocused)(void);
|
bool (*isFocused)(void);
|
||||||
|
bool (*isPassthroughEnabled)(void);
|
||||||
|
bool (*setPassthroughEnabled)(bool enable);
|
||||||
double (*update)(void);
|
double (*update)(void);
|
||||||
} HeadsetInterface;
|
} HeadsetInterface;
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,10 @@ static HeadsetOrigin desktop_getOriginType(void) {
|
||||||
return ORIGIN_HEAD;
|
return ORIGIN_HEAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void desktop_getDisplayDimensions(uint32_t* width, uint32_t* height) {
|
||||||
|
os_window_get_size(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
static double desktop_getDisplayTime(void) {
|
static double desktop_getDisplayTime(void) {
|
||||||
return state.nextDisplayTime - state.epoch;
|
return state.nextDisplayTime - state.epoch;
|
||||||
}
|
}
|
||||||
|
@ -83,10 +87,6 @@ static double desktop_getDeltaTime(void) {
|
||||||
return state.nextDisplayTime - state.prevDisplayTime;
|
return state.nextDisplayTime - state.prevDisplayTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void desktop_getDisplayDimensions(uint32_t* width, uint32_t* height) {
|
|
||||||
os_window_get_size(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t desktop_getViewCount(void) {
|
static uint32_t desktop_getViewCount(void) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -225,6 +225,14 @@ static bool desktop_isFocused(void) {
|
||||||
return state.focused;
|
return state.focused;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool desktop_isPassthroughEnabled(void) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool desktop_setPassthroughEnabled(bool enable) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static double desktop_update(void) {
|
static double desktop_update(void) {
|
||||||
bool front = os_is_key_down(KEY_W) || os_is_key_down(KEY_UP);
|
bool front = os_is_key_down(KEY_W) || os_is_key_down(KEY_UP);
|
||||||
bool back = os_is_key_down(KEY_S) || os_is_key_down(KEY_DOWN);
|
bool back = os_is_key_down(KEY_S) || os_is_key_down(KEY_DOWN);
|
||||||
|
@ -325,9 +333,9 @@ HeadsetInterface lovrHeadsetDesktopDriver = {
|
||||||
.destroy = desktop_destroy,
|
.destroy = desktop_destroy,
|
||||||
.getName = desktop_getName,
|
.getName = desktop_getName,
|
||||||
.getOriginType = desktop_getOriginType,
|
.getOriginType = desktop_getOriginType,
|
||||||
|
.getDisplayDimensions = desktop_getDisplayDimensions,
|
||||||
.getDisplayTime = desktop_getDisplayTime,
|
.getDisplayTime = desktop_getDisplayTime,
|
||||||
.getDeltaTime = desktop_getDeltaTime,
|
.getDeltaTime = desktop_getDeltaTime,
|
||||||
.getDisplayDimensions = desktop_getDisplayDimensions,
|
|
||||||
.getViewCount = desktop_getViewCount,
|
.getViewCount = desktop_getViewCount,
|
||||||
.getViewPose = desktop_getViewPose,
|
.getViewPose = desktop_getViewPose,
|
||||||
.getViewAngles = desktop_getViewAngles,
|
.getViewAngles = desktop_getViewAngles,
|
||||||
|
@ -348,5 +356,7 @@ HeadsetInterface lovrHeadsetDesktopDriver = {
|
||||||
.getPass = desktop_getPass,
|
.getPass = desktop_getPass,
|
||||||
.submit = desktop_submit,
|
.submit = desktop_submit,
|
||||||
.isFocused = desktop_isFocused,
|
.isFocused = desktop_isFocused,
|
||||||
|
.isPassthroughEnabled = desktop_isPassthroughEnabled,
|
||||||
|
.setPassthroughEnabled = desktop_setPassthroughEnabled,
|
||||||
.update = desktop_update
|
.update = desktop_update
|
||||||
};
|
};
|
||||||
|
|
|
@ -98,7 +98,13 @@ uintptr_t gpu_vk_get_queue(uint32_t* queueFamilyIndex, uint32_t* queueIndex);
|
||||||
X(xrEnumerateDisplayRefreshRatesFB)\
|
X(xrEnumerateDisplayRefreshRatesFB)\
|
||||||
X(xrRequestDisplayRefreshRateFB)\
|
X(xrRequestDisplayRefreshRateFB)\
|
||||||
X(xrQuerySystemTrackedKeyboardFB)\
|
X(xrQuerySystemTrackedKeyboardFB)\
|
||||||
X(xrCreateKeyboardSpaceFB)
|
X(xrCreateKeyboardSpaceFB)\
|
||||||
|
X(xrCreatePassthroughFB)\
|
||||||
|
X(xrDestroyPassthroughFB)\
|
||||||
|
X(xrPassthroughStartFB)\
|
||||||
|
X(xrPassthroughPauseFB)\
|
||||||
|
X(xrCreatePassthroughLayerFB)\
|
||||||
|
X(xrDestroyPassthroughLayerFB)
|
||||||
|
|
||||||
#define XR_DECLARE(fn) static PFN_##fn fn;
|
#define XR_DECLARE(fn) static PFN_##fn fn;
|
||||||
#define XR_LOAD(fn) xrGetInstanceProcAddr(state.instance, #fn, (PFN_xrVoidFunction*) &fn);
|
#define XR_LOAD(fn) xrGetInstanceProcAddr(state.instance, #fn, (PFN_xrVoidFunction*) &fn);
|
||||||
|
@ -156,6 +162,7 @@ static struct {
|
||||||
XrCompositionLayerProjection layers[1];
|
XrCompositionLayerProjection layers[1];
|
||||||
XrCompositionLayerProjectionView layerViews[2];
|
XrCompositionLayerProjectionView layerViews[2];
|
||||||
XrCompositionLayerDepthInfoKHR depthInfo[2];
|
XrCompositionLayerDepthInfoKHR depthInfo[2];
|
||||||
|
XrCompositionLayerPassthroughFB passthroughLayer;
|
||||||
XrFrameState frameState;
|
XrFrameState frameState;
|
||||||
TextureFormat depthFormat;
|
TextureFormat depthFormat;
|
||||||
Texture* textures[2][MAX_IMAGES];
|
Texture* textures[2][MAX_IMAGES];
|
||||||
|
@ -174,6 +181,9 @@ static struct {
|
||||||
XrPath actionFilters[MAX_DEVICES];
|
XrPath actionFilters[MAX_DEVICES];
|
||||||
XrHandTrackerEXT handTrackers[2];
|
XrHandTrackerEXT handTrackers[2];
|
||||||
XrControllerModelKeyMSFT controllerModelKeys[2];
|
XrControllerModelKeyMSFT controllerModelKeys[2];
|
||||||
|
XrPassthroughFB passthrough;
|
||||||
|
XrPassthroughLayerFB passthroughLayerHandle;
|
||||||
|
bool passthroughActive;
|
||||||
struct {
|
struct {
|
||||||
bool controllerModel;
|
bool controllerModel;
|
||||||
bool depth;
|
bool depth;
|
||||||
|
@ -185,6 +195,7 @@ static struct {
|
||||||
bool headless;
|
bool headless;
|
||||||
bool keyboardTracking;
|
bool keyboardTracking;
|
||||||
bool overlay;
|
bool overlay;
|
||||||
|
bool passthrough;
|
||||||
bool refreshRate;
|
bool refreshRate;
|
||||||
bool viveTrackers;
|
bool viveTrackers;
|
||||||
} features;
|
} features;
|
||||||
|
@ -371,6 +382,7 @@ static bool openxr_init(HeadsetConfig* config) {
|
||||||
{ "XR_FB_hand_tracking_aim", &state.features.handTrackingAim, true },
|
{ "XR_FB_hand_tracking_aim", &state.features.handTrackingAim, true },
|
||||||
{ "XR_FB_hand_tracking_mesh", &state.features.handTrackingMesh, true },
|
{ "XR_FB_hand_tracking_mesh", &state.features.handTrackingMesh, true },
|
||||||
{ "XR_FB_keyboard_tracking", &state.features.keyboardTracking, true },
|
{ "XR_FB_keyboard_tracking", &state.features.keyboardTracking, true },
|
||||||
|
{ "XR_FB_passthrough", &state.features.passthrough, true },
|
||||||
{ "XR_MND_headless", &state.features.headless, true },
|
{ "XR_MND_headless", &state.features.headless, true },
|
||||||
{ "XR_MSFT_controller_model", &state.features.controllerModel, true },
|
{ "XR_MSFT_controller_model", &state.features.controllerModel, true },
|
||||||
{ "XR_ULTRALEAP_hand_tracking_forearm", &state.features.handTrackingElbow, true },
|
{ "XR_ULTRALEAP_hand_tracking_forearm", &state.features.handTrackingElbow, true },
|
||||||
|
@ -413,24 +425,11 @@ static bool openxr_init(HeadsetConfig* config) {
|
||||||
|
|
||||||
XR_INIT(xrGetSystem(state.instance, &info, &state.system));
|
XR_INIT(xrGetSystem(state.instance, &info, &state.system));
|
||||||
|
|
||||||
XrSystemEyeGazeInteractionPropertiesEXT eyeGazeProperties = {
|
XrSystemEyeGazeInteractionPropertiesEXT eyeGazeProperties = { .type = XR_TYPE_SYSTEM_EYE_GAZE_INTERACTION_PROPERTIES_EXT };
|
||||||
.type = XR_TYPE_SYSTEM_EYE_GAZE_INTERACTION_PROPERTIES_EXT,
|
XrSystemHandTrackingPropertiesEXT handTrackingProperties = { .type = XR_TYPE_SYSTEM_HAND_TRACKING_PROPERTIES_EXT };
|
||||||
.supportsEyeGazeInteraction = false
|
XrSystemKeyboardTrackingPropertiesFB keyboardTrackingProperties = { .type = XR_TYPE_SYSTEM_KEYBOARD_TRACKING_PROPERTIES_FB };
|
||||||
};
|
XrSystemPassthroughProperties2FB passthroughProperties = { .type = XR_TYPE_SYSTEM_PASSTHROUGH_PROPERTIES2_FB };
|
||||||
|
XrSystemProperties properties = { .type = XR_TYPE_SYSTEM_PROPERTIES };
|
||||||
XrSystemHandTrackingPropertiesEXT handTrackingProperties = {
|
|
||||||
.type = XR_TYPE_SYSTEM_HAND_TRACKING_PROPERTIES_EXT,
|
|
||||||
.supportsHandTracking = false
|
|
||||||
};
|
|
||||||
|
|
||||||
XrSystemKeyboardTrackingPropertiesFB keyboardTrackingProperties = {
|
|
||||||
.type = XR_TYPE_SYSTEM_KEYBOARD_TRACKING_PROPERTIES_FB,
|
|
||||||
.supportsKeyboardTracking = false
|
|
||||||
};
|
|
||||||
|
|
||||||
XrSystemProperties properties = {
|
|
||||||
.type = XR_TYPE_SYSTEM_PROPERTIES
|
|
||||||
};
|
|
||||||
|
|
||||||
if (state.features.gaze) {
|
if (state.features.gaze) {
|
||||||
eyeGazeProperties.next = properties.next;
|
eyeGazeProperties.next = properties.next;
|
||||||
|
@ -447,10 +446,16 @@ static bool openxr_init(HeadsetConfig* config) {
|
||||||
properties.next = &keyboardTrackingProperties;
|
properties.next = &keyboardTrackingProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (state.features.passthrough) {
|
||||||
|
passthroughProperties.next = properties.next;
|
||||||
|
properties.next = &passthroughProperties;
|
||||||
|
}
|
||||||
|
|
||||||
XR_INIT(xrGetSystemProperties(state.instance, state.system, &properties));
|
XR_INIT(xrGetSystemProperties(state.instance, state.system, &properties));
|
||||||
state.features.gaze = eyeGazeProperties.supportsEyeGazeInteraction;
|
state.features.gaze = eyeGazeProperties.supportsEyeGazeInteraction;
|
||||||
state.features.handTracking = handTrackingProperties.supportsHandTracking;
|
state.features.handTracking = handTrackingProperties.supportsHandTracking;
|
||||||
state.features.keyboardTracking = keyboardTrackingProperties.supportsKeyboardTracking;
|
state.features.keyboardTracking = keyboardTrackingProperties.supportsKeyboardTracking;
|
||||||
|
state.features.passthrough = passthroughProperties.capabilities & XR_PASSTHROUGH_CAPABILITY_BIT_FB;
|
||||||
|
|
||||||
uint32_t viewConfigurationCount;
|
uint32_t viewConfigurationCount;
|
||||||
XrViewConfigurationType viewConfigurations[2];
|
XrViewConfigurationType viewConfigurations[2];
|
||||||
|
@ -1042,17 +1047,10 @@ static void openxr_start(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XrCompositionLayerFlags layerFlags = 0;
|
|
||||||
|
|
||||||
if (state.features.overlay) {
|
|
||||||
layerFlags = XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT | XR_COMPOSITION_LAYER_UNPREMULTIPLIED_ALPHA_BIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pre-init composition layer
|
// Pre-init composition layer
|
||||||
state.layers[0] = (XrCompositionLayerProjection) {
|
state.layers[0] = (XrCompositionLayerProjection) {
|
||||||
.type = XR_TYPE_COMPOSITION_LAYER_PROJECTION,
|
.type = XR_TYPE_COMPOSITION_LAYER_PROJECTION,
|
||||||
.space = state.referenceSpace,
|
.space = state.referenceSpace,
|
||||||
.layerFlags = layerFlags,
|
|
||||||
.viewCount = 2,
|
.viewCount = 2,
|
||||||
.views = state.layerViews
|
.views = state.layerViews
|
||||||
};
|
};
|
||||||
|
@ -1122,6 +1120,9 @@ static void openxr_stop(void) {
|
||||||
if (state.handTrackers[0]) xrDestroyHandTrackerEXT(state.handTrackers[0]);
|
if (state.handTrackers[0]) xrDestroyHandTrackerEXT(state.handTrackers[0]);
|
||||||
if (state.handTrackers[1]) xrDestroyHandTrackerEXT(state.handTrackers[1]);
|
if (state.handTrackers[1]) xrDestroyHandTrackerEXT(state.handTrackers[1]);
|
||||||
|
|
||||||
|
if (state.passthrough) xrDestroyPassthroughFB(state.passthrough);
|
||||||
|
if (state.passthroughLayerHandle) xrDestroyPassthroughLayerFB(state.passthroughLayerHandle);
|
||||||
|
|
||||||
for (size_t i = 0; i < MAX_DEVICES; i++) {
|
for (size_t i = 0; i < MAX_DEVICES; i++) {
|
||||||
if (state.spaces[i]) {
|
if (state.spaces[i]) {
|
||||||
xrDestroySpace(state.spaces[i]);
|
xrDestroySpace(state.spaces[i]);
|
||||||
|
@ -2055,13 +2056,13 @@ static void openxr_submit(void) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XrCompositionLayerBaseHeader const* layers[2];
|
||||||
|
|
||||||
XrFrameEndInfo info = {
|
XrFrameEndInfo info = {
|
||||||
.type = XR_TYPE_FRAME_END_INFO,
|
.type = XR_TYPE_FRAME_END_INFO,
|
||||||
.displayTime = state.frameState.predictedDisplayTime,
|
.displayTime = state.frameState.predictedDisplayTime,
|
||||||
.environmentBlendMode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE,
|
.environmentBlendMode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE,
|
||||||
.layers = (const XrCompositionLayerBaseHeader*[1]) {
|
.layers = layers
|
||||||
(XrCompositionLayerBaseHeader*) &state.layers[0]
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (state.features.depth) {
|
if (state.features.depth) {
|
||||||
|
@ -2081,9 +2082,22 @@ static void openxr_submit(void) {
|
||||||
XR(xrReleaseSwapchainImage(state.swapchain[DEPTH], NULL));
|
XR(xrReleaseSwapchainImage(state.swapchain[DEPTH], NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (state.passthroughActive) {
|
||||||
|
layers[0] = (const XrCompositionLayerBaseHeader*) &state.passthroughLayer;
|
||||||
|
layers[1] = (const XrCompositionLayerBaseHeader*) &state.layers[0];
|
||||||
|
info.layerCount = 2;
|
||||||
|
} else {
|
||||||
|
layers[0] = (const XrCompositionLayerBaseHeader*) &state.layers[0];
|
||||||
info.layerCount = 1;
|
info.layerCount = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (state.features.overlay || state.passthroughActive) {
|
||||||
|
state.layers[0].layerFlags = XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT | XR_COMPOSITION_LAYER_UNPREMULTIPLIED_ALPHA_BIT;
|
||||||
|
} else {
|
||||||
|
state.layers[0].layerFlags = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
XR(xrEndFrame(state.session, &info));
|
XR(xrEndFrame(state.session, &info));
|
||||||
state.began = false;
|
state.began = false;
|
||||||
state.waited = false;
|
state.waited = false;
|
||||||
|
@ -2093,6 +2107,67 @@ static bool openxr_isFocused(void) {
|
||||||
return state.sessionState == XR_SESSION_STATE_FOCUSED;
|
return state.sessionState == XR_SESSION_STATE_FOCUSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool openxr_isPassthroughEnabled(void) {
|
||||||
|
return state.passthroughActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool openxr_setPassthroughEnabled(bool enable) {
|
||||||
|
if (!state.features.passthrough) return false;
|
||||||
|
|
||||||
|
XrResult result = XR_SUCCESS;
|
||||||
|
|
||||||
|
if (!state.passthrough) {
|
||||||
|
XrPassthroughCreateInfoFB info = { .type = XR_TYPE_PASSTHROUGH_CREATE_INFO_FB };
|
||||||
|
result = xrCreatePassthroughFB(state.session, &info, &state.passthrough);
|
||||||
|
|
||||||
|
if (XR_FAILED(result)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
XrPassthroughLayerCreateInfoFB layerInfo = {
|
||||||
|
.type = XR_TYPE_PASSTHROUGH_LAYER_CREATE_INFO_FB,
|
||||||
|
.passthrough = state.passthrough,
|
||||||
|
.purpose = XR_PASSTHROUGH_LAYER_PURPOSE_RECONSTRUCTION_FB,
|
||||||
|
.flags = XR_PASSTHROUGH_IS_RUNNING_AT_CREATION_BIT_FB
|
||||||
|
};
|
||||||
|
|
||||||
|
result = xrCreatePassthroughLayerFB(state.session, &layerInfo, &state.passthroughLayerHandle);
|
||||||
|
|
||||||
|
if (XR_FAILED(result)) {
|
||||||
|
xrDestroyPassthroughFB(state.passthrough);
|
||||||
|
state.passthrough = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.passthroughLayer = (XrCompositionLayerPassthroughFB) {
|
||||||
|
.type = XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_FB,
|
||||||
|
.layerHandle = state.passthroughLayerHandle
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enable == state.passthroughActive) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enable) {
|
||||||
|
result = xrPassthroughStartFB(state.passthrough);
|
||||||
|
|
||||||
|
if (XR_SUCCEEDED(result)) {
|
||||||
|
state.passthroughActive = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = xrPassthroughPauseFB(state.passthrough);
|
||||||
|
|
||||||
|
if (XR_SUCCEEDED(result)) {
|
||||||
|
state.passthroughActive = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static double openxr_update(void) {
|
static double openxr_update(void) {
|
||||||
if (state.waited) return openxr_getDeltaTime();
|
if (state.waited) return openxr_getDeltaTime();
|
||||||
|
|
||||||
|
@ -2202,5 +2277,7 @@ HeadsetInterface lovrHeadsetOpenXRDriver = {
|
||||||
.getPass = openxr_getPass,
|
.getPass = openxr_getPass,
|
||||||
.submit = openxr_submit,
|
.submit = openxr_submit,
|
||||||
.isFocused = openxr_isFocused,
|
.isFocused = openxr_isFocused,
|
||||||
|
.isPassthroughEnabled = openxr_isPassthroughEnabled,
|
||||||
|
.setPassthroughEnabled = openxr_setPassthroughEnabled,
|
||||||
.update = openxr_update
|
.update = openxr_update
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,9 +5,9 @@ extern void webxr_start(void);
|
||||||
extern void webxr_destroy(void);
|
extern void webxr_destroy(void);
|
||||||
extern bool webxr_getName(char* name, size_t length);
|
extern bool webxr_getName(char* name, size_t length);
|
||||||
extern HeadsetOrigin webxr_getOriginType(void);
|
extern HeadsetOrigin webxr_getOriginType(void);
|
||||||
|
extern void webxr_getDisplayDimensions(uint32_t* width, uint32_t* height);
|
||||||
extern double webxr_getDisplayTime(void);
|
extern double webxr_getDisplayTime(void);
|
||||||
extern double webxr_getDeltaTime(void);
|
extern double webxr_getDeltaTime(void);
|
||||||
extern void webxr_getDisplayDimensions(uint32_t* width, uint32_t* height);
|
|
||||||
extern uint32_t webxr_getViewCount(void);
|
extern uint32_t webxr_getViewCount(void);
|
||||||
extern bool webxr_getViewPose(uint32_t view, float* position, float* orientation);
|
extern bool webxr_getViewPose(uint32_t view, float* position, float* orientation);
|
||||||
extern bool webxr_getViewAngles(uint32_t view, float* left, float* right, float* up, float* down);
|
extern bool webxr_getViewAngles(uint32_t view, float* left, float* right, float* up, float* down);
|
||||||
|
@ -26,6 +26,8 @@ extern struct ModelData* webxr_newModelData(Device device, bool animated);
|
||||||
extern bool webxr_animate(struct Model* model);
|
extern bool webxr_animate(struct Model* model);
|
||||||
extern void webxr_renderTo(void (*callback)(void*), void* userdata);
|
extern void webxr_renderTo(void (*callback)(void*), void* userdata);
|
||||||
extern bool webxr_isFocused(void);
|
extern bool webxr_isFocused(void);
|
||||||
|
extern bool webxr_isPassthroughEnabled(void);
|
||||||
|
extern bool webxr_setPassthroughEnabled(bool enable);
|
||||||
extern double webxr_update(void);
|
extern double webxr_update(void);
|
||||||
|
|
||||||
static bool webxrAttached = false;
|
static bool webxrAttached = false;
|
||||||
|
|
Loading…
Reference in New Issue