OpenXR recenter integrated

This commit is contained in:
Lubos 2022-05-04 16:19:48 +02:00
parent 08a4fc7fbf
commit 8e5f6414a6
5 changed files with 79 additions and 55 deletions

View file

@ -299,7 +299,6 @@ void VR_EnterVR( engine_t* engine, ovrJava java ) {
void VR_LeaveVR( engine_t* engine ) {
if (engine->appState.Session) {
OXR(xrDestroySpace(engine->appState.HeadSpace));
OXR(xrDestroySpace(engine->appState.LocalSpace));
// StageSpace is optional.
if (engine->appState.StageSpace != XR_NULL_HANDLE) {
OXR(xrDestroySpace(engine->appState.StageSpace));

View file

@ -63,6 +63,8 @@ typedef struct {
int *menuCursorX;
int *menuCursorY;
qboolean menuLeftHanded;
float recenterYaw;
} vr_clientinfo_t;
#endif //vr_clientinfo_h

View file

@ -23,6 +23,7 @@ extern vr_clientinfo_t vr;
extern cvar_t *vr_heightAdjust;
XrView* projections;
GLboolean stageSupported = GL_FALSE;
void VR_UpdateStageBounds(ovrApp* pappState) {
XrExtent2Df stageBounds = {};
@ -161,6 +162,60 @@ void VR_GetResolution(engine_t* engine, int *pWidth, int *pHeight)
}
}
void VR_Recenter(engine_t* engine) {
// Delete previous space instances
qboolean spacesAlreadyExisted = qfalse;
if (engine->appState.StageSpace != XR_NULL_HANDLE) {
OXR(xrDestroySpace(engine->appState.StageSpace));
}
if (engine->appState.FakeStageSpace != XR_NULL_HANDLE) {
OXR(xrDestroySpace(engine->appState.FakeStageSpace));
spacesAlreadyExisted = qtrue;
}
// Create a space to the first path
XrReferenceSpaceCreateInfo spaceCreateInfo = {};
spaceCreateInfo.type = XR_TYPE_REFERENCE_SPACE_CREATE_INFO;
spaceCreateInfo.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_VIEW;
spaceCreateInfo.poseInReferenceSpace.orientation.w = 1.0f;
// Calculate recenter reference
if (engine->appState.CurrentSpace != XR_NULL_HANDLE) {
vr.recenterYaw += radians(vr.clientviewangles[YAW]);
spaceCreateInfo.poseInReferenceSpace.orientation.x = 0;
spaceCreateInfo.poseInReferenceSpace.orientation.y = sin(vr.recenterYaw / 2);
spaceCreateInfo.poseInReferenceSpace.orientation.z = 0;
spaceCreateInfo.poseInReferenceSpace.orientation.w = cos(vr.recenterYaw / 2);
}
// Create a default stage space to use if SPACE_TYPE_STAGE is not
// supported, or calls to xrGetReferenceSpaceBoundsRect fail.
spaceCreateInfo.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_LOCAL;
spaceCreateInfo.poseInReferenceSpace.position.y = -1.6750f;
OXR(xrCreateReferenceSpace(engine->appState.Session, &spaceCreateInfo, &engine->appState.FakeStageSpace));
ALOGV("Created fake stage space from local space with offset");
engine->appState.CurrentSpace = engine->appState.FakeStageSpace;
if (stageSupported) {
spaceCreateInfo.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_STAGE;
spaceCreateInfo.poseInReferenceSpace.position.y = 0.0f;
OXR(xrCreateReferenceSpace(engine->appState.Session, &spaceCreateInfo, &engine->appState.StageSpace));
ALOGV("Created stage space");
engine->appState.CurrentSpace = engine->appState.StageSpace;
}
// Update menu orientation
if (spacesAlreadyExisted) {
vec3_t rotation = {0, 0, 0};
XrSpaceLocation loc = {};
loc.type = XR_TYPE_SPACE_LOCATION;
OXR(xrLocateSpace(engine->appState.HeadSpace, engine->appState.CurrentSpace, engine->predictedDisplayTime, &loc));
QuatToYawPitchRoll(loc.pose.orientation, rotation, vr.hmdorientation);
vr.menuYaw = vr.hmdorientation[YAW];
}
}
void VR_InitRenderer( engine_t* engine ) {
#if ENABLE_GL_DEBUG
glEnable(GL_DEBUG_OUTPUT);
@ -227,7 +282,6 @@ void VR_InitRenderer( engine_t* engine ) {
OXR(xrEnumerateReferenceSpaces(
engine->appState.Session, numOutputSpaces, &numOutputSpaces, referenceSpaces));
GLboolean stageSupported = GL_FALSE;
for (uint32_t i = 0; i < numOutputSpaces; i++) {
if (referenceSpaces[i] == XR_REFERENCE_SPACE_TYPE_STAGE) {
stageSupported = GL_TRUE;
@ -244,26 +298,7 @@ void VR_InitRenderer( engine_t* engine ) {
spaceCreateInfo.poseInReferenceSpace.orientation.w = 1.0f;
OXR(xrCreateReferenceSpace(engine->appState.Session, &spaceCreateInfo, &engine->appState.HeadSpace));
spaceCreateInfo.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_LOCAL;
OXR(xrCreateReferenceSpace(engine->appState.Session, &spaceCreateInfo, &engine->appState.LocalSpace));
// Create a default stage space to use if SPACE_TYPE_STAGE is not
// supported, or calls to xrGetReferenceSpaceBoundsRect fail.
{
spaceCreateInfo.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_LOCAL;
spaceCreateInfo.poseInReferenceSpace.position.y = -1.6750f;
OXR(xrCreateReferenceSpace(engine->appState.Session, &spaceCreateInfo, &engine->appState.FakeStageSpace));
ALOGV("Created fake stage space from local space with offset");
engine->appState.CurrentSpace = engine->appState.FakeStageSpace;
}
if (stageSupported) {
spaceCreateInfo.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_STAGE;
spaceCreateInfo.poseInReferenceSpace.position.y = 0.0f;
OXR(xrCreateReferenceSpace(engine->appState.Session, &spaceCreateInfo, &engine->appState.StageSpace));
ALOGV("Created stage space");
engine->appState.CurrentSpace = engine->appState.StageSpace;
}
VR_Recenter(engine);
projections = (XrView*)(malloc(ovrMaxNumEyes * sizeof(XrView)));
@ -324,7 +359,7 @@ void VR_DrawFrame( engine_t* engine ) {
GLboolean stageBoundsDirty = GL_TRUE;
if (ovrApp_HandleXrEvents(&engine->appState)) {
vr.menuYaw = vr.hmdorientation[YAW];
VR_Recenter(engine);
}
if (engine->appState.SessionActive == GL_FALSE) {
return;
@ -360,44 +395,34 @@ void VR_DrawFrame( engine_t* engine ) {
beginFrameDesc.next = NULL;
OXR(xrBeginFrame(engine->appState.Session, &beginFrameDesc));
// We extract Yaw, Pitch, Roll instead of directly using the orientation
// to allow "additional" yaw manipulation with mouse/controller.
XrSpaceLocation loc = {};
loc.type = XR_TYPE_SPACE_LOCATION;
OXR(xrLocateSpace(
engine->appState.HeadSpace, engine->appState.CurrentSpace, frameState.predictedDisplayTime, &loc));
OXR(xrLocateSpace(engine->appState.HeadSpace, engine->appState.CurrentSpace, frameState.predictedDisplayTime, &loc));
XrPosef xfStageFromHead = loc.pose;
OXR(xrLocateSpace(
engine->appState.HeadSpace, engine->appState.LocalSpace, frameState.predictedDisplayTime, &loc));
const XrQuaternionf quatHmd = xfStageFromHead.orientation;
const XrVector3f positionHmd = xfStageFromHead.position;
vec3_t rotation = {0, 0, 0};
QuatToYawPitchRoll(quatHmd, rotation, vr.hmdorientation);
VectorSet(vr.hmdposition, positionHmd.x, positionHmd.y + vr_heightAdjust->value, positionHmd.z);
{
// We extract Yaw, Pitch, Roll instead of directly using the orientation
// to allow "additional" yaw manipulation with mouse/controller.
XrSpaceLocation loc = {};
loc.type = XR_TYPE_SPACE_LOCATION;
OXR(xrLocateSpace(engine->appState.HeadSpace, engine->appState.CurrentSpace, frameState.predictedDisplayTime, &loc));
XrPosef xfStageFromHead = loc.pose;
const XrQuaternionf quatHmd = xfStageFromHead.orientation;
const XrVector3f positionHmd = xfStageFromHead.position;
vec3_t rotation = {0, 0, 0};
QuatToYawPitchRoll(quatHmd, rotation, vr.hmdorientation);
VectorSet(vr.hmdposition, positionHmd.x, positionHmd.y + vr_heightAdjust->value, positionHmd.z);
//Position
VectorSubtract(vr.hmdposition_last, vr.hmdposition, vr.hmdposition_delta);
//Position
VectorSubtract(vr.hmdposition_last, vr.hmdposition, vr.hmdposition_delta);
//Keep this for our records
VectorCopy(vr.hmdposition, vr.hmdposition_last);
//Keep this for our records
VectorCopy(vr.hmdposition, vr.hmdposition_last);
//Orientation
VectorSubtract(vr.hmdorientation_last, vr.hmdorientation, vr.hmdorientation_delta);
//Orientation
VectorSubtract(vr.hmdorientation_last, vr.hmdorientation, vr.hmdorientation_delta);
//Keep this for our records
VectorCopy(vr.hmdorientation, vr.hmdorientation_last);
//Keep this for our records
VectorCopy(vr.hmdorientation, vr.hmdorientation_last);
// View yaw delta
const float clientview_yaw = vr.clientviewangles[YAW] - vr.hmdorientation[YAW];
vr.clientview_yaw_delta = vr.clientview_yaw_last - clientview_yaw;
vr.clientview_yaw_last = clientview_yaw;
}
// View yaw delta
const float clientview_yaw = vr.clientviewangles[YAW] - vr.hmdorientation[YAW];
vr.clientview_yaw_delta = vr.clientview_yaw_last - clientview_yaw;
vr.clientview_yaw_last = clientview_yaw;
XrViewLocateInfo projectionInfo = {};
projectionInfo.type = XR_TYPE_VIEW_LOCATE_INFO;

View file

@ -236,7 +236,6 @@ void ovrApp_Clear(ovrApp* app) {
memset(&app->ViewConfigurationView, 0, ovrMaxNumEyes * sizeof(XrViewConfigurationView));
app->SystemId = XR_NULL_SYSTEM_ID;
app->HeadSpace = XR_NULL_HANDLE;
app->LocalSpace = XR_NULL_HANDLE;
app->StageSpace = XR_NULL_HANDLE;
app->FakeStageSpace = XR_NULL_HANDLE;
app->CurrentSpace = XR_NULL_HANDLE;

View file

@ -79,7 +79,6 @@ typedef struct {
XrViewConfigurationView ViewConfigurationView[ovrMaxNumEyes];
XrSystemId SystemId;
XrSpace HeadSpace;
XrSpace LocalSpace;
XrSpace StageSpace;
XrSpace FakeStageSpace;
XrSpace CurrentSpace;