diff --git a/Common/VR/VRRenderer.cpp b/Common/VR/VRRenderer.cpp index 8e623f0791..48bad0f901 100644 --- a/Common/VR/VRRenderer.cpp +++ b/Common/VR/VRRenderer.cpp @@ -457,23 +457,31 @@ ovrMatrix4f VR_GetMatrix( VRMatrix matrix ) { } else if ((matrix == VR_VIEW_MATRIX_LEFT_EYE) || (matrix == VR_VIEW_MATRIX_RIGHT_EYE)) { XrPosef invView = matrix == VR_VIEW_MATRIX_LEFT_EYE ? invViewTransform[0] : invViewTransform[1]; - if (vrConfig[VR_CONFIG_INVERTED_PROJECTION]) { - vec3_t rotation = {0, 0, 0}; - QuatToYawPitchRoll(invView.orientation, rotation, rotation); - XrQuaternionf pitch = XrQuaternionf_CreateFromVectorAngle({1, 0, 0}, -radians(rotation[PITCH])); - XrQuaternionf yaw = XrQuaternionf_CreateFromVectorAngle({0, 1, 0}, radians(rotation[YAW])); - XrQuaternionf roll = XrQuaternionf_CreateFromVectorAngle({0, 0, 1}, radians(rotation[ROLL])); - invView.orientation = XrQuaternionf_Multiply(roll, XrQuaternionf_Multiply(pitch, yaw)); - invView.position.x *= -1.0f; - invView.position.y *= -1.0f; - invView.position.z *= -1.0f; + // 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; + + // ensure there is maximally one axis to mirror + if (mx + my + mz < 0) { + mx *= -1.0f; + my *= -1.0f; + mz *= -1.0f; } else { invView = XrPosef_Inverse(invView); } + + // create updated quaternion + if (mx + my + mz < 3 - 0.001f) { + vec3_t rotation = {0, 0, 0}; + QuatToYawPitchRoll(invView.orientation, rotation, rotation); + XrQuaternionf pitch = XrQuaternionf_CreateFromVectorAngle({1, 0, 0}, mx * radians(rotation[0])); + XrQuaternionf yaw = XrQuaternionf_CreateFromVectorAngle({0, 1, 0}, my * radians(rotation[1])); + XrQuaternionf roll = XrQuaternionf_CreateFromVectorAngle({0, 0, 1}, mz * radians(rotation[2])); + invView.orientation = XrQuaternionf_Multiply(roll, XrQuaternionf_Multiply(pitch, yaw)); + } + output = ovrMatrix4f_CreateFromQuaternion(&invView.orientation); - output.M[0][3] = 0;//invView.position.x; - output.M[1][3] = 0;//invView.position.y; - output.M[2][3] = 0;//invView.position.z; } else { assert(false); } diff --git a/Common/VR/VRRenderer.h b/Common/VR/VRRenderer.h index 78b465ba18..803d0299db 100644 --- a/Common/VR/VRRenderer.h +++ b/Common/VR/VRRenderer.h @@ -4,7 +4,9 @@ enum VRConfig { VR_CONFIG_MODE, - VR_CONFIG_INVERTED_PROJECTION, + VR_CONFIG_MIRROR_AXIS_X, + VR_CONFIG_MIRROR_AXIS_Y, + VR_CONFIG_MIRROR_AXIS_Z, VR_CONFIG_3D_GEOMETRY_COUNT, VR_CONFIG_FOV_SCALE, VR_CONFIG_MAX diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index a111f1cd49..e834588d49 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -347,6 +347,7 @@ void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid, bool useBu if ((VR_GetConfig(VR_CONFIG_MODE) == VR_MODE_FLAT_SCREEN) || is2D) { memcpy(&flippedMatrix, gstate.projMatrix, 16 * sizeof(float)); } else { + // Update the projection matrix ovrMatrix4f hmdProjection = VR_GetMatrix(VR_PROJECTION_MATRIX_LEFT_EYE); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { @@ -356,6 +357,17 @@ void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid, bool useBu } } memcpy(&flippedMatrix, hmdProjection.M, 16 * sizeof(float)); + + // Assign axis mirroring + 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); + } 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); + } } #else memcpy(&flippedMatrix, gstate.projMatrix, 16 * sizeof(float)); @@ -520,11 +532,6 @@ void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid, bool useBu memcpy(gameView.M, m4x4, 16 * sizeof(float)); // Get view matrix from the headset - if (gstate.projMatrix[0] * gstate.projMatrix[5] * gstate.projMatrix[10] > 0) { - VR_SetConfig(VR_CONFIG_INVERTED_PROJECTION, true); - } else { - VR_SetConfig(VR_CONFIG_INVERTED_PROJECTION, false); - } ovrMatrix4f hmdView = VR_GetMatrix(VR_VIEW_MATRIX_LEFT_EYE); // Combine the matrices