OpenXR - 6DoF head movement support added

This commit is contained in:
Lubos 2022-07-31 20:05:08 +02:00
parent 8117f05395
commit e6b14cb473
7 changed files with 31 additions and 12 deletions

View File

@ -221,6 +221,7 @@ bool GLRenderManager::ThreadFrame() {
VR_SetConfig(VR_CONFIG_3D_GEOMETRY_COUNT, VR_GetConfig(VR_CONFIG_3D_GEOMETRY_COUNT) / 2); VR_SetConfig(VR_CONFIG_3D_GEOMETRY_COUNT, VR_GetConfig(VR_CONFIG_3D_GEOMETRY_COUNT) / 2);
// Set customizations // Set customizations
VR_SetConfig(VR_CONFIG_6DOF, g_Config.bEnable6DoF);
VR_SetConfig(VR_CONFIG_FOV_SCALE, g_Config.iFieldOfViewPercentage); VR_SetConfig(VR_CONFIG_FOV_SCALE, g_Config.iFieldOfViewPercentage);
// hack to quick enable 2D mode in game // hack to quick enable 2D mode in game

View File

@ -156,7 +156,9 @@ void VR_Recenter(engine_t* engine) {
// Create a default stage space to use if SPACE_TYPE_STAGE is not // Create a default stage space to use if SPACE_TYPE_STAGE is not
// supported, or calls to xrGetReferenceSpaceBoundsRect fail. // supported, or calls to xrGetReferenceSpaceBoundsRect fail.
spaceCreateInfo.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_LOCAL; spaceCreateInfo.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_LOCAL;
#ifdef OPENXR_FLOOR_STAGE
spaceCreateInfo.poseInReferenceSpace.position.y = -1.6750f; spaceCreateInfo.poseInReferenceSpace.position.y = -1.6750f;
#endif
OXR(xrCreateReferenceSpace(engine->appState.Session, &spaceCreateInfo, &engine->appState.FakeStageSpace)); OXR(xrCreateReferenceSpace(engine->appState.Session, &spaceCreateInfo, &engine->appState.FakeStageSpace));
ALOGV("Created fake stage space from local space with offset"); ALOGV("Created fake stage space from local space with offset");
engine->appState.CurrentSpace = engine->appState.FakeStageSpace; engine->appState.CurrentSpace = engine->appState.FakeStageSpace;
@ -166,7 +168,9 @@ void VR_Recenter(engine_t* engine) {
spaceCreateInfo.poseInReferenceSpace.position.y = 0.0; spaceCreateInfo.poseInReferenceSpace.position.y = 0.0;
OXR(xrCreateReferenceSpace(engine->appState.Session, &spaceCreateInfo, &engine->appState.StageSpace)); OXR(xrCreateReferenceSpace(engine->appState.Session, &spaceCreateInfo, &engine->appState.StageSpace));
ALOGV("Created stage space"); ALOGV("Created stage space");
#ifdef OPENXR_FLOOR_STAGE
engine->appState.CurrentSpace = engine->appState.StageSpace; engine->appState.CurrentSpace = engine->appState.StageSpace;
#endif
} }
// Update menu orientation // Update menu orientation
@ -309,8 +313,6 @@ void VR_BeginFrame( engine_t* engine ) {
for (int eye = 0; eye < ovrMaxNumEyes; eye++) { for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[eye]; ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[eye];
int swapchainIndex = frameBuffer->TextureSwapChainIndex;
int glFramebuffer = frameBuffer->FrameBuffers[swapchainIndex];
ovrFramebuffer_Acquire(frameBuffer); ovrFramebuffer_Acquire(frameBuffer);
ovrFramebuffer_SetCurrent(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]; XrPosef invView = matrix == VR_VIEW_MATRIX_LEFT_EYE ? invViewTransform[0] : invViewTransform[1];
// get axis mirroring configuration // get axis mirroring configuration
float mx = vrConfig[VR_CONFIG_MIRROR_AXIS_X] ? -1 : 1; float mx = vrConfig[VR_CONFIG_MIRROR_PITCH] ? -1 : 1;
float my = vrConfig[VR_CONFIG_MIRROR_AXIS_Y] ? -1 : 1; float my = vrConfig[VR_CONFIG_MIRROR_YAW] ? -1 : 1;
float mz = vrConfig[VR_CONFIG_MIRROR_AXIS_Z] ? -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) { if (mx + my + mz < 0) {
mx *= -1.0f; mx *= -1.0f;
my *= -1.0f; my *= -1.0f;
@ -482,6 +484,11 @@ ovrMatrix4f VR_GetMatrix( VRMatrix matrix ) {
} }
output = ovrMatrix4f_CreateFromQuaternion(&invView.orientation); 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 { } else {
assert(false); assert(false);
} }

View File

@ -4,9 +4,13 @@
enum VRConfig { enum VRConfig {
VR_CONFIG_MODE, VR_CONFIG_MODE,
VR_CONFIG_6DOF,
VR_CONFIG_MIRROR_AXIS_X, VR_CONFIG_MIRROR_AXIS_X,
VR_CONFIG_MIRROR_AXIS_Y, VR_CONFIG_MIRROR_AXIS_Y,
VR_CONFIG_MIRROR_AXIS_Z, VR_CONFIG_MIRROR_AXIS_Z,
VR_CONFIG_MIRROR_PITCH,
VR_CONFIG_MIRROR_YAW,
VR_CONFIG_MIRROR_ROLL,
VR_CONFIG_3D_GEOMETRY_COUNT, VR_CONFIG_3D_GEOMETRY_COUNT,
VR_CONFIG_FOV_SCALE, VR_CONFIG_FOV_SCALE,
VR_CONFIG_MAX VR_CONFIG_MAX

View File

@ -1207,6 +1207,7 @@ static ConfigSetting themeSettings[] = {
static ConfigSetting vrSettings[] = { static ConfigSetting vrSettings[] = {
ConfigSetting("VREnable", &g_Config.bEnableVR, true), ConfigSetting("VREnable", &g_Config.bEnableVR, true),
ConfigSetting("VREnable6DoF", &g_Config.bEnable6DoF, false),
ConfigSetting("VRFieldOfView", &g_Config.iFieldOfViewPercentage, 50), ConfigSetting("VRFieldOfView", &g_Config.iFieldOfViewPercentage, 50),
}; };

View File

@ -455,6 +455,7 @@ public:
// Virtual reality // Virtual reality
bool bEnableVR; bool bEnableVR;
bool bEnable6DoF;
int iFieldOfViewPercentage; int iFieldOfViewPercentage;
// Debugger // Debugger

View File

@ -359,14 +359,17 @@ void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid, bool useBu
memcpy(&flippedMatrix, hmdProjection.M, 16 * sizeof(float)); memcpy(&flippedMatrix, hmdProjection.M, 16 * sizeof(float));
// Assign axis mirroring // 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) { if (gstate.projMatrix[0] * gstate.projMatrix[5] * gstate.projMatrix[10] > 0) {
VR_SetConfig(VR_CONFIG_MIRROR_AXIS_X, false); VR_SetConfig(VR_CONFIG_MIRROR_PITCH, false);
VR_SetConfig(VR_CONFIG_MIRROR_AXIS_Y, true); VR_SetConfig(VR_CONFIG_MIRROR_YAW, true);
VR_SetConfig(VR_CONFIG_MIRROR_AXIS_Z, true); VR_SetConfig(VR_CONFIG_MIRROR_ROLL, true);
} else { } else {
VR_SetConfig(VR_CONFIG_MIRROR_AXIS_X, false); VR_SetConfig(VR_CONFIG_MIRROR_PITCH, false);
VR_SetConfig(VR_CONFIG_MIRROR_AXIS_Y, false); VR_SetConfig(VR_CONFIG_MIRROR_YAW, false);
VR_SetConfig(VR_CONFIG_MIRROR_AXIS_Z, false); VR_SetConfig(VR_CONFIG_MIRROR_ROLL, false);
} }
} }
#else #else

View File

@ -1113,6 +1113,8 @@ void GameSettingsScreen::CreateViews() {
LinearLayout *vrSettings = AddTab("GameSettingsVR", ms->T("VR")); LinearLayout *vrSettings = AddTab("GameSettingsVR", ms->T("VR"));
vrSettings->Add(new ItemHeader(vr->T("Virtual reality"))); vrSettings->Add(new ItemHeader(vr->T("Virtual reality")));
vrSettings->Add(new CheckBox(&g_Config.bEnableVR, vr->T("Enable 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"))); 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); vrFieldOfView->SetEnabledPtr(&g_Config.bEnableVR);
} }