From e6b14cb47315ae9fc02c73701d8a71d871f75048 Mon Sep 17 00:00:00 2001 From: Lubos Date: Sun, 31 Jul 2022 20:05:08 +0200 Subject: [PATCH] OpenXR - 6DoF head movement support added --- Common/GPU/OpenGL/GLRenderManager.cpp | 1 + Common/VR/VRRenderer.cpp | 19 +++++++++++++------ Common/VR/VRRenderer.h | 4 ++++ Core/Config.cpp | 1 + Core/Config.h | 1 + GPU/GLES/ShaderManagerGLES.cpp | 15 +++++++++------ UI/GameSettingsScreen.cpp | 2 ++ 7 files changed, 31 insertions(+), 12 deletions(-) diff --git a/Common/GPU/OpenGL/GLRenderManager.cpp b/Common/GPU/OpenGL/GLRenderManager.cpp index 7169bebeab..4a4fee3a30 100644 --- a/Common/GPU/OpenGL/GLRenderManager.cpp +++ b/Common/GPU/OpenGL/GLRenderManager.cpp @@ -221,6 +221,7 @@ bool GLRenderManager::ThreadFrame() { VR_SetConfig(VR_CONFIG_3D_GEOMETRY_COUNT, VR_GetConfig(VR_CONFIG_3D_GEOMETRY_COUNT) / 2); // Set customizations + VR_SetConfig(VR_CONFIG_6DOF, g_Config.bEnable6DoF); VR_SetConfig(VR_CONFIG_FOV_SCALE, g_Config.iFieldOfViewPercentage); // hack to quick enable 2D mode in game diff --git a/Common/VR/VRRenderer.cpp b/Common/VR/VRRenderer.cpp index 48bad0f901..bf08e126a7 100644 --- a/Common/VR/VRRenderer.cpp +++ b/Common/VR/VRRenderer.cpp @@ -156,7 +156,9 @@ void VR_Recenter(engine_t* engine) { // 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; +#ifdef OPENXR_FLOOR_STAGE spaceCreateInfo.poseInReferenceSpace.position.y = -1.6750f; +#endif 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; @@ -166,7 +168,9 @@ void VR_Recenter(engine_t* engine) { spaceCreateInfo.poseInReferenceSpace.position.y = 0.0; OXR(xrCreateReferenceSpace(engine->appState.Session, &spaceCreateInfo, &engine->appState.StageSpace)); ALOGV("Created stage space"); +#ifdef OPENXR_FLOOR_STAGE engine->appState.CurrentSpace = engine->appState.StageSpace; +#endif } // Update menu orientation @@ -309,8 +313,6 @@ void VR_BeginFrame( engine_t* engine ) { for (int eye = 0; eye < ovrMaxNumEyes; eye++) { ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[eye]; - int swapchainIndex = frameBuffer->TextureSwapChainIndex; - int glFramebuffer = frameBuffer->FrameBuffers[swapchainIndex]; ovrFramebuffer_Acquire(frameBuffer); ovrFramebuffer_SetCurrent(frameBuffer); @@ -458,11 +460,11 @@ ovrMatrix4f VR_GetMatrix( VRMatrix matrix ) { XrPosef invView = matrix == VR_VIEW_MATRIX_LEFT_EYE ? invViewTransform[0] : invViewTransform[1]; // get axis mirroring configuration - float mx = vrConfig[VR_CONFIG_MIRROR_AXIS_X] ? -1 : 1; - float my = vrConfig[VR_CONFIG_MIRROR_AXIS_Y] ? -1 : 1; - float mz = vrConfig[VR_CONFIG_MIRROR_AXIS_Z] ? -1 : 1; + float mx = vrConfig[VR_CONFIG_MIRROR_PITCH] ? -1 : 1; + float my = vrConfig[VR_CONFIG_MIRROR_YAW] ? -1 : 1; + float mz = vrConfig[VR_CONFIG_MIRROR_ROLL] ? -1 : 1; - // ensure there is maximally one axis to mirror + // ensure there is maximally one axis to mirror rotation if (mx + my + mz < 0) { mx *= -1.0f; my *= -1.0f; @@ -482,6 +484,11 @@ ovrMatrix4f VR_GetMatrix( VRMatrix matrix ) { } output = ovrMatrix4f_CreateFromQuaternion(&invView.orientation); + if (vrConfig[VR_CONFIG_6DOF]) { + output.M[0][3] -= hmdposition[0] * (vrConfig[VR_CONFIG_MIRROR_AXIS_X] ? -1.0f : 1.0f); + output.M[1][3] -= hmdposition[1] * (vrConfig[VR_CONFIG_MIRROR_AXIS_Y] ? -1.0f : 1.0f); + output.M[2][3] -= hmdposition[2] * (vrConfig[VR_CONFIG_MIRROR_AXIS_Z] ? -1.0f : 1.0f); + } } else { assert(false); } diff --git a/Common/VR/VRRenderer.h b/Common/VR/VRRenderer.h index 803d0299db..d417dce09d 100644 --- a/Common/VR/VRRenderer.h +++ b/Common/VR/VRRenderer.h @@ -4,9 +4,13 @@ enum VRConfig { VR_CONFIG_MODE, + VR_CONFIG_6DOF, VR_CONFIG_MIRROR_AXIS_X, VR_CONFIG_MIRROR_AXIS_Y, VR_CONFIG_MIRROR_AXIS_Z, + VR_CONFIG_MIRROR_PITCH, + VR_CONFIG_MIRROR_YAW, + VR_CONFIG_MIRROR_ROLL, VR_CONFIG_3D_GEOMETRY_COUNT, VR_CONFIG_FOV_SCALE, VR_CONFIG_MAX diff --git a/Core/Config.cpp b/Core/Config.cpp index 1569867467..102d8a0b4e 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -1207,6 +1207,7 @@ static ConfigSetting themeSettings[] = { static ConfigSetting vrSettings[] = { ConfigSetting("VREnable", &g_Config.bEnableVR, true), + ConfigSetting("VREnable6DoF", &g_Config.bEnable6DoF, false), ConfigSetting("VRFieldOfView", &g_Config.iFieldOfViewPercentage, 50), }; diff --git a/Core/Config.h b/Core/Config.h index aac1e8d91f..cdb0bbfff2 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -455,6 +455,7 @@ public: // Virtual reality bool bEnableVR; + bool bEnable6DoF; int iFieldOfViewPercentage; // Debugger diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index e834588d49..5d08cca694 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -359,14 +359,17 @@ void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid, bool useBu memcpy(&flippedMatrix, hmdProjection.M, 16 * sizeof(float)); // Assign axis mirroring + VR_SetConfig(VR_CONFIG_MIRROR_AXIS_X, gstate.projMatrix[0] < 0); + VR_SetConfig(VR_CONFIG_MIRROR_AXIS_Y, gstate.projMatrix[5] < 0); + VR_SetConfig(VR_CONFIG_MIRROR_AXIS_Z, gstate.projMatrix[10] > 0); if (gstate.projMatrix[0] * gstate.projMatrix[5] * gstate.projMatrix[10] > 0) { - VR_SetConfig(VR_CONFIG_MIRROR_AXIS_X, false); - VR_SetConfig(VR_CONFIG_MIRROR_AXIS_Y, true); - VR_SetConfig(VR_CONFIG_MIRROR_AXIS_Z, true); + VR_SetConfig(VR_CONFIG_MIRROR_PITCH, false); + VR_SetConfig(VR_CONFIG_MIRROR_YAW, true); + VR_SetConfig(VR_CONFIG_MIRROR_ROLL, true); } else { - VR_SetConfig(VR_CONFIG_MIRROR_AXIS_X, false); - VR_SetConfig(VR_CONFIG_MIRROR_AXIS_Y, false); - VR_SetConfig(VR_CONFIG_MIRROR_AXIS_Z, false); + VR_SetConfig(VR_CONFIG_MIRROR_PITCH, false); + VR_SetConfig(VR_CONFIG_MIRROR_YAW, false); + VR_SetConfig(VR_CONFIG_MIRROR_ROLL, false); } } #else diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 49f0211dc6..369e30ac6e 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -1113,6 +1113,8 @@ void GameSettingsScreen::CreateViews() { LinearLayout *vrSettings = AddTab("GameSettingsVR", ms->T("VR")); vrSettings->Add(new ItemHeader(vr->T("Virtual reality"))); vrSettings->Add(new CheckBox(&g_Config.bEnableVR, vr->T("Enable virtual reality"))); + CheckBox *vr6DoF = vrSettings->Add(new CheckBox(&g_Config.bEnable6DoF, vr->T("Enable 6 degrees of freedom movement"))); + vr6DoF->SetEnabledPtr(&g_Config.bEnableVR); PopupSliderChoice *vrFieldOfView = vrSettings->Add(new PopupSliderChoice(&g_Config.iFieldOfViewPercentage, 50, 150, vr->T("Field of view scale", "Headset's field of view scale"), 10, screenManager(), vr->T("% of native FoV"))); vrFieldOfView->SetEnabledPtr(&g_Config.bEnableVR); }