From 637bb57bc6bdcf5339b385010e3e2b3da7664758 Mon Sep 17 00:00:00 2001 From: Lubos Date: Sun, 6 Nov 2022 20:42:28 +0100 Subject: [PATCH 1/9] OpenXR - Get rid of ovrMatrix4f structure --- Common/VR/PPSSPPVR.cpp | 25 +-- Common/VR/VRMath.cpp | 329 ++++++++------------------------------- Common/VR/VRMath.h | 20 +-- Common/VR/VRRenderer.cpp | 71 ++++++--- Common/VR/VRRenderer.h | 2 +- 5 files changed, 136 insertions(+), 311 deletions(-) diff --git a/Common/VR/PPSSPPVR.cpp b/Common/VR/PPSSPPVR.cpp index 537844b073..bce2f00227 100644 --- a/Common/VR/PPSSPPVR.cpp +++ b/Common/VR/PPSSPPVR.cpp @@ -9,6 +9,8 @@ #endif #include "Common/GPU/Vulkan/VulkanContext.h" +#include "Common/Math/lin/matrix4x4.h" + #include "Core/HLE/sceDisplay.h" #include "Core/Config.h" #include "Core/KeyMap.h" @@ -584,15 +586,13 @@ void UpdateVRProjection(float* projMatrix, float* leftEye, float* rightEye) { float* dst[] = {leftEye, rightEye}; VRMatrix enums[] = {VR_PROJECTION_MATRIX_LEFT_EYE, VR_PROJECTION_MATRIX_RIGHT_EYE}; for (int index = 0; index < 2; index++) { - ovrMatrix4f hmdProjection = VR_GetMatrix(enums[index]); - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - if ((hmdProjection.M[i][j] > 0) != (projMatrix[i * 4 + j] > 0)) { - hmdProjection.M[i][j] *= -1.0f; - } + float* hmdProjection = VR_GetMatrix(enums[index]); + for (int i = 0; i < 16; i++) { + if ((hmdProjection[i] > 0) != (projMatrix[i] > 0)) { + hmdProjection[i] *= -1.0f; } } - memcpy(dst[index], hmdProjection.M, 16 * sizeof(float)); + memcpy(dst[index], hmdProjection, 16 * sizeof(float)); } } @@ -602,14 +602,15 @@ void UpdateVRView(float* leftEye, float* rightEye) { for (int index = 0; index < 2; index++) { // Get view matrix from the game - ovrMatrix4f gameView; - memcpy(gameView.M, dst[index], 16 * sizeof(float)); + Lin::Matrix4x4 gameView = {}; + memcpy(gameView.m, dst[index], 16 * sizeof(float)); // Get view matrix from the headset - ovrMatrix4f hmdView = VR_GetMatrix(enums[index]); + Lin::Matrix4x4 hmdView = {}; + memcpy(hmdView.m, VR_GetMatrix(enums[index]), 16 * sizeof(float)); // Combine the matrices - ovrMatrix4f renderView = ovrMatrix4f_Multiply(&hmdView, &gameView); - memcpy(dst[index], renderView.M, 16 * sizeof(float)); + Lin::Matrix4x4 renderView = hmdView * gameView; + memcpy(dst[index], renderView.m, 16 * sizeof(float)); } } diff --git a/Common/VR/VRMath.cpp b/Common/VR/VRMath.cpp index bafdff75ea..2fd7f1d538 100644 --- a/Common/VR/VRMath.cpp +++ b/Common/VR/VRMath.cpp @@ -1,6 +1,7 @@ #define _USE_MATH_DEFINES #include +#include #include "VRMath.h" @@ -15,240 +16,21 @@ float ToRadians(float deg) { /* ================================================================================ -ovrMatrix4f - -================================================================================ -*/ - -float ovrMatrix4f_Minor(const ovrMatrix4f* m, int r0, int r1, int r2, int c0, int c1, int c2) { - return m->M[r0][c0] * (m->M[r1][c1] * m->M[r2][c2] - m->M[r2][c1] * m->M[r1][c2]) - - m->M[r0][c1] * (m->M[r1][c0] * m->M[r2][c2] - m->M[r2][c0] * m->M[r1][c2]) + - m->M[r0][c2] * (m->M[r1][c0] * m->M[r2][c1] - m->M[r2][c0] * m->M[r1][c1]); -} - -ovrMatrix4f ovrMatrix4f_CreateFromQuaternion(const XrQuaternionf* q) { - const float ww = q->w * q->w; - const float xx = q->x * q->x; - const float yy = q->y * q->y; - const float zz = q->z * q->z; - - ovrMatrix4f out; - out.M[0][0] = ww + xx - yy - zz; - out.M[0][1] = 2 * (q->x * q->y - q->w * q->z); - out.M[0][2] = 2 * (q->x * q->z + q->w * q->y); - out.M[0][3] = 0; - - out.M[1][0] = 2 * (q->x * q->y + q->w * q->z); - out.M[1][1] = ww - xx + yy - zz; - out.M[1][2] = 2 * (q->y * q->z - q->w * q->x); - out.M[1][3] = 0; - - out.M[2][0] = 2 * (q->x * q->z - q->w * q->y); - out.M[2][1] = 2 * (q->y * q->z + q->w * q->x); - out.M[2][2] = ww - xx - yy + zz; - out.M[2][3] = 0; - - out.M[3][0] = 0; - out.M[3][1] = 0; - out.M[3][2] = 0; - out.M[3][3] = 1; - return out; -} - -ovrMatrix4f ovrMatrix4f_CreateProjectionFov( - const float angleLeft, - const float angleRight, - const float angleUp, - const float angleDown, - const float nearZ, - const float farZ) { - - const float tanAngleLeft = tanf(angleLeft); - const float tanAngleRight = tanf(angleRight); - - const float tanAngleDown = tanf(angleDown); - const float tanAngleUp = tanf(angleUp); - - const float tanAngleWidth = tanAngleRight - tanAngleLeft; - - // Set to tanAngleDown - tanAngleUp for a clip space with positive Y - // down (Vulkan). Set to tanAngleUp - tanAngleDown for a clip space with - // positive Y up (OpenGL / D3D / Metal). - const float tanAngleHeight = tanAngleUp - tanAngleDown; - - // Set to nearZ for a [-1,1] Z clip space (OpenGL / OpenGL ES). - // Set to zero for a [0,1] Z clip space (Vulkan / D3D / Metal). - const float offsetZ = nearZ; - - ovrMatrix4f result; - if (farZ <= nearZ) { - // place the far plane at infinity - result.M[0][0] = 2 / tanAngleWidth; - result.M[0][1] = 0; - result.M[0][2] = (tanAngleRight + tanAngleLeft) / tanAngleWidth; - result.M[0][3] = 0; - - result.M[1][0] = 0; - result.M[1][1] = 2 / tanAngleHeight; - result.M[1][2] = (tanAngleUp + tanAngleDown) / tanAngleHeight; - result.M[1][3] = 0; - - result.M[2][0] = 0; - result.M[2][1] = 0; - result.M[2][2] = -1; - result.M[2][3] = -(nearZ + offsetZ); - - result.M[3][0] = 0; - result.M[3][1] = 0; - result.M[3][2] = -1; - result.M[3][3] = 0; - } else { - // normal projection - result.M[0][0] = 2 / tanAngleWidth; - result.M[0][1] = 0; - result.M[0][2] = (tanAngleRight + tanAngleLeft) / tanAngleWidth; - result.M[0][3] = 0; - - result.M[1][0] = 0; - result.M[1][1] = 2 / tanAngleHeight; - result.M[1][2] = (tanAngleUp + tanAngleDown) / tanAngleHeight; - result.M[1][3] = 0; - - result.M[2][0] = 0; - result.M[2][1] = 0; - result.M[2][2] = -(farZ + offsetZ) / (farZ - nearZ); - result.M[2][3] = -(farZ * (nearZ + offsetZ)) / (farZ - nearZ); - - result.M[3][0] = 0; - result.M[3][1] = 0; - result.M[3][2] = -1; - result.M[3][3] = 0; - } - return result; -} - -ovrMatrix4f ovrMatrix4f_CreateRotation(const float radiansX, const float radiansY, const float radiansZ) { - const float sinX = sinf(radiansX); - const float cosX = cosf(radiansX); - const ovrMatrix4f rotationX = { - {{1, 0, 0, 0}, {0, cosX, -sinX, 0}, {0, sinX, cosX, 0}, {0, 0, 0, 1}}}; - const float sinY = sinf(radiansY); - const float cosY = cosf(radiansY); - const ovrMatrix4f rotationY = { - {{cosY, 0, sinY, 0}, {0, 1, 0, 0}, {-sinY, 0, cosY, 0}, {0, 0, 0, 1}}}; - const float sinZ = sinf(radiansZ); - const float cosZ = cosf(radiansZ); - const ovrMatrix4f rotationZ = { - {{cosZ, -sinZ, 0, 0}, {sinZ, cosZ, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}}; - const ovrMatrix4f rotationXY = ovrMatrix4f_Multiply(&rotationY, &rotationX); - return ovrMatrix4f_Multiply(&rotationZ, &rotationXY); -} - -ovrMatrix4f ovrMatrix4f_Inverse(const ovrMatrix4f* m) { - const float rcpDet = 1.0f / - (m->M[0][0] * ovrMatrix4f_Minor(m, 1, 2, 3, 1, 2, 3) - - m->M[0][1] * ovrMatrix4f_Minor(m, 1, 2, 3, 0, 2, 3) + - m->M[0][2] * ovrMatrix4f_Minor(m, 1, 2, 3, 0, 1, 3) - - m->M[0][3] * ovrMatrix4f_Minor(m, 1, 2, 3, 0, 1, 2)); - ovrMatrix4f out; - out.M[0][0] = ovrMatrix4f_Minor(m, 1, 2, 3, 1, 2, 3) * rcpDet; - out.M[0][1] = -ovrMatrix4f_Minor(m, 0, 2, 3, 1, 2, 3) * rcpDet; - out.M[0][2] = ovrMatrix4f_Minor(m, 0, 1, 3, 1, 2, 3) * rcpDet; - out.M[0][3] = -ovrMatrix4f_Minor(m, 0, 1, 2, 1, 2, 3) * rcpDet; - out.M[1][0] = -ovrMatrix4f_Minor(m, 1, 2, 3, 0, 2, 3) * rcpDet; - out.M[1][1] = ovrMatrix4f_Minor(m, 0, 2, 3, 0, 2, 3) * rcpDet; - out.M[1][2] = -ovrMatrix4f_Minor(m, 0, 1, 3, 0, 2, 3) * rcpDet; - out.M[1][3] = ovrMatrix4f_Minor(m, 0, 1, 2, 0, 2, 3) * rcpDet; - out.M[2][0] = ovrMatrix4f_Minor(m, 1, 2, 3, 0, 1, 3) * rcpDet; - out.M[2][1] = -ovrMatrix4f_Minor(m, 0, 2, 3, 0, 1, 3) * rcpDet; - out.M[2][2] = ovrMatrix4f_Minor(m, 0, 1, 3, 0, 1, 3) * rcpDet; - out.M[2][3] = -ovrMatrix4f_Minor(m, 0, 1, 2, 0, 1, 3) * rcpDet; - out.M[3][0] = -ovrMatrix4f_Minor(m, 1, 2, 3, 0, 1, 2) * rcpDet; - out.M[3][1] = ovrMatrix4f_Minor(m, 0, 2, 3, 0, 1, 2) * rcpDet; - out.M[3][2] = -ovrMatrix4f_Minor(m, 0, 1, 3, 0, 1, 2) * rcpDet; - out.M[3][3] = ovrMatrix4f_Minor(m, 0, 1, 2, 0, 1, 2) * rcpDet; - return out; -} - -/// Use left-multiplication to accumulate transformations. -ovrMatrix4f ovrMatrix4f_Multiply(const ovrMatrix4f* a, const ovrMatrix4f* b) { - ovrMatrix4f out; - out.M[0][0] = a->M[0][0] * b->M[0][0] + a->M[0][1] * b->M[1][0] + a->M[0][2] * b->M[2][0] + - a->M[0][3] * b->M[3][0]; - out.M[1][0] = a->M[1][0] * b->M[0][0] + a->M[1][1] * b->M[1][0] + a->M[1][2] * b->M[2][0] + - a->M[1][3] * b->M[3][0]; - out.M[2][0] = a->M[2][0] * b->M[0][0] + a->M[2][1] * b->M[1][0] + a->M[2][2] * b->M[2][0] + - a->M[2][3] * b->M[3][0]; - out.M[3][0] = a->M[3][0] * b->M[0][0] + a->M[3][1] * b->M[1][0] + a->M[3][2] * b->M[2][0] + - a->M[3][3] * b->M[3][0]; - - out.M[0][1] = a->M[0][0] * b->M[0][1] + a->M[0][1] * b->M[1][1] + a->M[0][2] * b->M[2][1] + - a->M[0][3] * b->M[3][1]; - out.M[1][1] = a->M[1][0] * b->M[0][1] + a->M[1][1] * b->M[1][1] + a->M[1][2] * b->M[2][1] + - a->M[1][3] * b->M[3][1]; - out.M[2][1] = a->M[2][0] * b->M[0][1] + a->M[2][1] * b->M[1][1] + a->M[2][2] * b->M[2][1] + - a->M[2][3] * b->M[3][1]; - out.M[3][1] = a->M[3][0] * b->M[0][1] + a->M[3][1] * b->M[1][1] + a->M[3][2] * b->M[2][1] + - a->M[3][3] * b->M[3][1]; - - out.M[0][2] = a->M[0][0] * b->M[0][2] + a->M[0][1] * b->M[1][2] + a->M[0][2] * b->M[2][2] + - a->M[0][3] * b->M[3][2]; - out.M[1][2] = a->M[1][0] * b->M[0][2] + a->M[1][1] * b->M[1][2] + a->M[1][2] * b->M[2][2] + - a->M[1][3] * b->M[3][2]; - out.M[2][2] = a->M[2][0] * b->M[0][2] + a->M[2][1] * b->M[1][2] + a->M[2][2] * b->M[2][2] + - a->M[2][3] * b->M[3][2]; - out.M[3][2] = a->M[3][0] * b->M[0][2] + a->M[3][1] * b->M[1][2] + a->M[3][2] * b->M[2][2] + - a->M[3][3] * b->M[3][2]; - - out.M[0][3] = a->M[0][0] * b->M[0][3] + a->M[0][1] * b->M[1][3] + a->M[0][2] * b->M[2][3] + - a->M[0][3] * b->M[3][3]; - out.M[1][3] = a->M[1][0] * b->M[0][3] + a->M[1][1] * b->M[1][3] + a->M[1][2] * b->M[2][3] + - a->M[1][3] * b->M[3][3]; - out.M[2][3] = a->M[2][0] * b->M[0][3] + a->M[2][1] * b->M[1][3] + a->M[2][2] * b->M[2][3] + - a->M[2][3] * b->M[3][3]; - out.M[3][3] = a->M[3][0] * b->M[0][3] + a->M[3][1] * b->M[1][3] + a->M[3][2] * b->M[2][3] + - a->M[3][3] * b->M[3][3]; - return out; -} - -XrVector3f ovrMatrix4f_ToEulerAngles(const ovrMatrix4f* m) { - XrVector4f v1 = {0, 0, -1, 0}; - XrVector4f v2 = {1, 0, 0, 0}; - XrVector4f v3 = {0, 1, 0, 0}; - - XrVector4f forwardInVRSpace = XrVector4f_MultiplyMatrix4f(m, &v1); - XrVector4f rightInVRSpace = XrVector4f_MultiplyMatrix4f(m, &v2); - XrVector4f upInVRSpace = XrVector4f_MultiplyMatrix4f(m, &v3); - - XrVector3f forward = {-forwardInVRSpace.z, -forwardInVRSpace.x, forwardInVRSpace.y}; - XrVector3f right = {-rightInVRSpace.z, -rightInVRSpace.x, rightInVRSpace.y}; - XrVector3f up = {-upInVRSpace.z, -upInVRSpace.x, upInVRSpace.y}; - - XrVector3f forwardNormal = XrVector3f_Normalized(forward); - XrVector3f rightNormal = XrVector3f_Normalized(right); - XrVector3f upNormal = XrVector3f_Normalized(up); - - return XrVector3f_GetAnglesFromVectors(forwardNormal, rightNormal, upNormal); -} - -/* -================================================================================ - XrPosef ================================================================================ */ XrPosef XrPosef_Identity() { - XrPosef r; - r.orientation.x = 0; - r.orientation.y = 0; - r.orientation.z = 0; - r.orientation.w = 1; - r.position.x = 0; - r.position.y = 0; - r.position.z = 0; - return r; + XrPosef r; + r.orientation.x = 0; + r.orientation.y = 0; + r.orientation.z = 0; + r.orientation.w = 1; + r.position.x = 0; + r.position.y = 0; + r.position.z = 0; + return r; } XrPosef XrPosef_Inverse(const XrPosef a) { @@ -258,18 +40,6 @@ XrPosef XrPosef_Inverse(const XrPosef a) { return b; } -XrPosef XrPosef_Multiply(const XrPosef a, const XrPosef b) { - XrPosef c; - c.orientation = XrQuaternionf_Multiply(a.orientation, b.orientation); - c.position = XrPosef_Transform(a, b.position); - return c; -} - -XrVector3f XrPosef_Transform(const XrPosef a, const XrVector3f v) { - XrVector3f r0 = XrQuaternionf_Rotate(a.orientation, v); - return XrVector3f_Add(r0, a.position); -} - /* ================================================================================ @@ -329,8 +99,56 @@ XrVector3f XrQuaternionf_Rotate(const XrQuaternionf a, const XrVector3f v) { } XrVector3f XrQuaternionf_ToEulerAngles(const XrQuaternionf q) { - ovrMatrix4f m = ovrMatrix4f_CreateFromQuaternion( &q ); - return ovrMatrix4f_ToEulerAngles(&m); + float M[16]; + XrQuaternionf_ToMatrix4f( &q, M); + + XrVector4f v1 = {0, 0, -1, 0}; + XrVector4f v2 = {1, 0, 0, 0}; + XrVector4f v3 = {0, 1, 0, 0}; + + XrVector4f forwardInVRSpace = XrVector4f_MultiplyMatrix4f(M, &v1); + XrVector4f rightInVRSpace = XrVector4f_MultiplyMatrix4f(M, &v2); + XrVector4f upInVRSpace = XrVector4f_MultiplyMatrix4f(M, &v3); + + XrVector3f forward = {-forwardInVRSpace.z, -forwardInVRSpace.x, forwardInVRSpace.y}; + XrVector3f right = {-rightInVRSpace.z, -rightInVRSpace.x, rightInVRSpace.y}; + XrVector3f up = {-upInVRSpace.z, -upInVRSpace.x, upInVRSpace.y}; + + XrVector3f forwardNormal = XrVector3f_Normalized(forward); + XrVector3f rightNormal = XrVector3f_Normalized(right); + XrVector3f upNormal = XrVector3f_Normalized(up); + + return XrVector3f_GetAnglesFromVectors(forwardNormal, rightNormal, upNormal); +} + +void XrQuaternionf_ToMatrix4f(const XrQuaternionf* q, float* matrix) { + const float ww = q->w * q->w; + const float xx = q->x * q->x; + const float yy = q->y * q->y; + const float zz = q->z * q->z; + + float M[4][4]; + M[0][0] = ww + xx - yy - zz; + M[0][1] = 2 * (q->x * q->y - q->w * q->z); + M[0][2] = 2 * (q->x * q->z + q->w * q->y); + M[0][3] = 0; + + M[1][0] = 2 * (q->x * q->y + q->w * q->z); + M[1][1] = ww - xx + yy - zz; + M[1][2] = 2 * (q->y * q->z - q->w * q->x); + M[1][3] = 0; + + M[2][0] = 2 * (q->x * q->z - q->w * q->y); + M[2][1] = 2 * (q->y * q->z + q->w * q->x); + M[2][2] = ww - xx - yy + zz; + M[2][3] = 0; + + M[3][0] = 0; + M[3][1] = 0; + M[3][2] = 0; + M[3][3] = 1; + + memcpy(matrix, &M, sizeof(float) * 16); } /* @@ -341,22 +159,10 @@ XrVector3f, XrVector4f ================================================================================ */ -float XrVector3f_Length(const XrVector3f v) { - return sqrtf(XrVector3f_LengthSquared(v)); -} - float XrVector3f_LengthSquared(const XrVector3f v) { return v.x * v.x + v.y * v.y + v.z * v.z;; } -XrVector3f XrVector3f_Add(const XrVector3f u, const XrVector3f v) { - XrVector3f w; - w.x = u.x + v.x; - w.y = u.y + v.y; - w.z = u.z + v.z; - return w; -} - XrVector3f XrVector3f_GetAnglesFromVectors(const XrVector3f forward, const XrVector3f right, const XrVector3f up) { float sr, sp, sy, cr, cp, cy; @@ -397,7 +203,7 @@ XrVector3f XrVector3f_GetAnglesFromVectors(const XrVector3f forward, const XrVec } XrVector3f XrVector3f_Normalized(const XrVector3f v) { - float rcpLen = 1.0f / XrVector3f_Length(v); + float rcpLen = 1.0f / sqrtf(XrVector3f_LengthSquared(v)); return XrVector3f_ScalarMultiply(v, rcpLen); } @@ -409,11 +215,14 @@ XrVector3f XrVector3f_ScalarMultiply(const XrVector3f v, float scale) { return u; } -XrVector4f XrVector4f_MultiplyMatrix4f(const ovrMatrix4f* a, const XrVector4f* v) { +XrVector4f XrVector4f_MultiplyMatrix4f(const float* m, const XrVector4f* v) { + float M[4][4]; + memcpy(&M, m, sizeof(float) * 16); + XrVector4f out; - out.x = a->M[0][0] * v->x + a->M[0][1] * v->y + a->M[0][2] * v->z + a->M[0][3] * v->w; - out.y = a->M[1][0] * v->x + a->M[1][1] * v->y + a->M[1][2] * v->z + a->M[1][3] * v->w; - out.z = a->M[2][0] * v->x + a->M[2][1] * v->y + a->M[2][2] * v->z + a->M[2][3] * v->w; - out.w = a->M[3][0] * v->x + a->M[3][1] * v->y + a->M[3][2] * v->z + a->M[3][3] * v->w; + out.x = M[0][0] * v->x + M[0][1] * v->y + M[0][2] * v->z + M[0][3] * v->w; + out.y = M[1][0] * v->x + M[1][1] * v->y + M[1][2] * v->z + M[1][3] * v->w; + out.z = M[2][0] * v->x + M[2][1] * v->y + M[2][2] * v->z + M[2][3] * v->w; + out.w = M[3][0] * v->x + M[3][1] * v->y + M[3][2] * v->z + M[3][3] * v->w; return out; } diff --git a/Common/VR/VRMath.h b/Common/VR/VRMath.h index eb801ac73f..20317f4a8d 100644 --- a/Common/VR/VRMath.h +++ b/Common/VR/VRMath.h @@ -7,27 +7,12 @@ #define EPSILON 0.001f #endif -typedef struct { - float M[4][4]; -} ovrMatrix4f; - float ToDegrees(float rad); float ToRadians(float deg); -// ovrMatrix4f -float ovrMatrix4f_Minor(const ovrMatrix4f* m, int r0, int r1, int r2, int c0, int c1, int c2); -ovrMatrix4f ovrMatrix4f_CreateFromQuaternion(const XrQuaternionf* q); -ovrMatrix4f ovrMatrix4f_CreateProjectionFov(const float angleLeft, const float angleRight, const float angleUp, const float angleDown, const float nearZ, const float farZ); -ovrMatrix4f ovrMatrix4f_CreateRotation(const float radiansX, const float radiansY, const float radiansZ); -ovrMatrix4f ovrMatrix4f_Inverse(const ovrMatrix4f* m); -ovrMatrix4f ovrMatrix4f_Multiply(const ovrMatrix4f* a, const ovrMatrix4f* b); -XrVector3f ovrMatrix4f_ToEulerAngles(const ovrMatrix4f* m); - // XrPosef XrPosef XrPosef_Identity(); XrPosef XrPosef_Inverse(const XrPosef a); -XrPosef XrPosef_Multiply(const XrPosef a, const XrPosef b); -XrVector3f XrPosef_Transform(const XrPosef a, const XrVector3f v); // XrQuaternionf XrQuaternionf XrQuaternionf_CreateFromVectorAngle(const XrVector3f axis, const float angle); @@ -35,12 +20,11 @@ XrQuaternionf XrQuaternionf_Inverse(const XrQuaternionf q); XrQuaternionf XrQuaternionf_Multiply(const XrQuaternionf a, const XrQuaternionf b); XrVector3f XrQuaternionf_Rotate(const XrQuaternionf a, const XrVector3f v); XrVector3f XrQuaternionf_ToEulerAngles(const XrQuaternionf q); +void XrQuaternionf_ToMatrix4f(const XrQuaternionf* q, float* m); // XrVector3f, XrVector4f -float XrVector3f_Length(const XrVector3f v); float XrVector3f_LengthSquared(const XrVector3f v); -XrVector3f XrVector3f_Add(const XrVector3f u, const XrVector3f v); XrVector3f XrVector3f_GetAnglesFromVectors(const XrVector3f forward, const XrVector3f right, const XrVector3f up); XrVector3f XrVector3f_Normalized(const XrVector3f v); XrVector3f XrVector3f_ScalarMultiply(const XrVector3f v, float scale); -XrVector4f XrVector4f_MultiplyMatrix4f(const ovrMatrix4f* a, const XrVector4f* v); +XrVector4f XrVector4f_MultiplyMatrix4f(const float* m, const XrVector4f* v); diff --git a/Common/VR/VRRenderer.cpp b/Common/VR/VRRenderer.cpp index e67d4ecd62..cbe69f2307 100644 --- a/Common/VR/VRRenderer.cpp +++ b/Common/VR/VRRenderer.cpp @@ -16,7 +16,7 @@ XrPosef invViewTransform[2]; XrFrameState frameState = {}; bool initialized = false; bool stageSupported = false; -ovrMatrix4f vrMatrix[VR_MATRIX_COUNT]; +float vrMatrix[VR_MATRIX_COUNT][16]; int vrConfig[VR_CONFIG_MAX] = {}; float vrConfigFloat[VR_CONFIG_FLOAT_MAX] = {}; @@ -306,8 +306,35 @@ bool VR_InitFrame( engine_t* engine ) { // Update matrices for (int matrix = 0; matrix < VR_MATRIX_COUNT; matrix++) { if ((matrix == VR_PROJECTION_MATRIX_LEFT_EYE) || (matrix == VR_PROJECTION_MATRIX_RIGHT_EYE)) { - float nearPlane = VR_GetConfigFloat(VR_CONFIG_FOV_SCALE) / 200.0f; - vrMatrix[matrix] = ovrMatrix4f_CreateProjectionFov(fov.angleLeft, fov.angleRight, fov.angleUp, fov.angleDown, nearPlane, 0.0f ); + float nearZ = VR_GetConfigFloat(VR_CONFIG_FOV_SCALE) / 200.0f; + float tanAngleLeft = tanf(fov.angleLeft); + float tanAngleRight = tanf(fov.angleRight); + float tanAngleDown = tanf(fov.angleDown); + float tanAngleUp = tanf(fov.angleUp); + + float M[4][4]; + M[0][0] = 2 / (tanAngleRight - tanAngleLeft); + M[0][1] = 0; + M[0][2] = (tanAngleRight + tanAngleLeft) / (tanAngleRight - tanAngleLeft); + M[0][3] = 0; + + M[1][0] = 0; + M[1][1] = 2 / (tanAngleUp - tanAngleDown); + M[1][2] = (tanAngleUp + tanAngleDown) / (tanAngleUp - tanAngleDown); + M[1][3] = 0; + + // place the far plane at infinity + M[2][0] = 0; + M[2][1] = 0; + M[2][2] = -1; + M[2][3] = -(nearZ + nearZ); + + M[3][0] = 0; + M[3][1] = 0; + M[3][2] = -1; + M[3][3] = 0; + + memcpy(vrMatrix[matrix], M, sizeof(float) * 16); } else if ((matrix == VR_VIEW_MATRIX_LEFT_EYE) || (matrix == VR_VIEW_MATRIX_RIGHT_EYE)) { bool flatScreen = false; XrPosef invView = invViewTransform[0]; @@ -340,36 +367,39 @@ bool VR_InitFrame( engine_t* engine ) { invView.orientation = XrQuaternionf_Multiply(roll, XrQuaternionf_Multiply(pitch, yaw)); } - vrMatrix[matrix] = ovrMatrix4f_CreateFromQuaternion(&invView.orientation); + float M[16]; + XrQuaternionf_ToMatrix4f(&invView.orientation, M); + memcpy(&M, M, sizeof(float) * 16); + float scale = VR_GetConfigFloat(VR_CONFIG_6DOF_SCALE); if (!flatScreen && vrConfig[VR_CONFIG_6DOF_ENABLED]) { - vrMatrix[matrix].M[0][3] -= hmdposition.x * (vrConfig[VR_CONFIG_MIRROR_AXIS_X] ? -1.0f : 1.0f) * scale; - vrMatrix[matrix].M[1][3] -= hmdposition.y * (vrConfig[VR_CONFIG_MIRROR_AXIS_Y] ? -1.0f : 1.0f) * scale; - vrMatrix[matrix].M[2][3] -= hmdposition.z * (vrConfig[VR_CONFIG_MIRROR_AXIS_Z] ? -1.0f : 1.0f) * scale; + M[12] -= hmdposition.x * (vrConfig[VR_CONFIG_MIRROR_AXIS_X] ? -1.0f : 1.0f) * scale; + M[13] -= hmdposition.y * (vrConfig[VR_CONFIG_MIRROR_AXIS_Y] ? -1.0f : 1.0f) * scale; + M[14] -= hmdposition.z * (vrConfig[VR_CONFIG_MIRROR_AXIS_Z] ? -1.0f : 1.0f) * scale; } if (fabsf(VR_GetConfigFloat(VR_CONFIG_CAMERA_DISTANCE)) > 0.0f) { XrVector3f forward = {0.0f, 0.0f, VR_GetConfigFloat(VR_CONFIG_CAMERA_DISTANCE) * scale}; forward = XrQuaternionf_Rotate(invView.orientation, forward); forward = XrVector3f_ScalarMultiply(forward, vrConfig[VR_CONFIG_MIRROR_AXIS_Z] ? -1.0f : 1.0f); - vrMatrix[matrix].M[0][3] += forward.x; - vrMatrix[matrix].M[1][3] += forward.y; - vrMatrix[matrix].M[2][3] += forward.z; + M[12] += forward.x; + M[13] += forward.y; + M[14] += forward.z; } if (fabsf(VR_GetConfigFloat(VR_CONFIG_CAMERA_HEIGHT)) > 0.0f) { XrVector3f up = {0.0f, -VR_GetConfigFloat(VR_CONFIG_CAMERA_HEIGHT) * scale, 0.0f}; up = XrQuaternionf_Rotate(invView.orientation, up); up = XrVector3f_ScalarMultiply(up, vrConfig[VR_CONFIG_MIRROR_AXIS_Y] ? -1.0f : 1.0f); - vrMatrix[matrix].M[0][3] += up.x; - vrMatrix[matrix].M[1][3] += up.y; - vrMatrix[matrix].M[2][3] += up.z; + M[12] += up.x; + M[13] += up.y; + M[14] += up.z; } if (fabsf(VR_GetConfigFloat(VR_CONFIG_CAMERA_SIDE)) > 0.0f) { XrVector3f side = {-VR_GetConfigFloat(VR_CONFIG_CAMERA_SIDE) * scale, 0.0f, 0.0f}; side = XrQuaternionf_Rotate(invView.orientation, side); side = XrVector3f_ScalarMultiply(side, vrConfig[VR_CONFIG_MIRROR_AXIS_X] ? -1.0f : 1.0f); - vrMatrix[matrix].M[0][3] += side.x; - vrMatrix[matrix].M[1][3] += side.y; - vrMatrix[matrix].M[2][3] += side.z; + M[12] += side.x; + M[13] += side.y; + M[14] += side.z; } if (vrConfig[VR_CONFIG_HAS_UNIT_SCALE] && (matrix == VR_VIEW_MATRIX_RIGHT_EYE)) { float dx = fabs(invViewTransform[1].position.x - invViewTransform[0].position.x); @@ -379,10 +409,11 @@ bool VR_InitFrame( engine_t* engine ) { XrVector3f separation = {ipd * scale, 0.0f, 0.0f}; separation = XrQuaternionf_Rotate(invView.orientation, separation); separation = XrVector3f_ScalarMultiply(separation, vrConfig[VR_CONFIG_MIRROR_AXIS_Z] ? -1.0f : 1.0f); - vrMatrix[matrix].M[0][3] -= separation.x; - vrMatrix[matrix].M[1][3] -= separation.y; - vrMatrix[matrix].M[2][3] -= separation.z; + M[12] -= separation.x; + M[13] -= separation.y; + M[14] -= separation.z; } + memcpy(vrMatrix[matrix], M, sizeof(float) * 16); } else { assert(false); } @@ -550,6 +581,6 @@ void* VR_BindFramebuffer(engine_t *engine) { return ovrFramebuffer_SetCurrent(&engine->appState.Renderer.FrameBuffer[fboIndex]); } -ovrMatrix4f VR_GetMatrix( VRMatrix matrix ) { +float* VR_GetMatrix( VRMatrix matrix ) { return vrMatrix[matrix]; } diff --git a/Common/VR/VRRenderer.h b/Common/VR/VRRenderer.h index bd041ca366..3600aec081 100644 --- a/Common/VR/VRRenderer.h +++ b/Common/VR/VRRenderer.h @@ -67,4 +67,4 @@ float VR_GetConfigFloat( VRConfigFloat config ); void VR_SetConfigFloat( VRConfigFloat config, float value ); void* VR_BindFramebuffer(engine_t *engine); -ovrMatrix4f VR_GetMatrix( VRMatrix matrix ); +float* VR_GetMatrix( VRMatrix matrix ); From 5c9e6968a5142c94bbb4a1da78fab80d259471d2 Mon Sep 17 00:00:00 2001 From: Lubos Date: Sun, 6 Nov 2022 21:21:13 +0100 Subject: [PATCH 2/9] OpenXR - Get rid of separate projection matrices --- Common/VR/PPSSPPVR.cpp | 15 ++++++--------- Common/VR/VRRenderer.cpp | 36 ++++++++++++++++++------------------ Common/VR/VRRenderer.h | 3 +-- 3 files changed, 25 insertions(+), 29 deletions(-) diff --git a/Common/VR/PPSSPPVR.cpp b/Common/VR/PPSSPPVR.cpp index bce2f00227..a548eb452f 100644 --- a/Common/VR/PPSSPPVR.cpp +++ b/Common/VR/PPSSPPVR.cpp @@ -583,17 +583,14 @@ void UpdateVRParams(float* projMatrix) { } void UpdateVRProjection(float* projMatrix, float* leftEye, float* rightEye) { - float* dst[] = {leftEye, rightEye}; - VRMatrix enums[] = {VR_PROJECTION_MATRIX_LEFT_EYE, VR_PROJECTION_MATRIX_RIGHT_EYE}; - for (int index = 0; index < 2; index++) { - float* hmdProjection = VR_GetMatrix(enums[index]); - for (int i = 0; i < 16; i++) { - if ((hmdProjection[i] > 0) != (projMatrix[i] > 0)) { - hmdProjection[i] *= -1.0f; - } + float* hmdProjection = VR_GetMatrix(VR_PROJECTION_MATRIX); + for (int i = 0; i < 16; i++) { + if ((hmdProjection[i] > 0) != (projMatrix[i] > 0)) { + hmdProjection[i] *= -1.0f; } - memcpy(dst[index], hmdProjection, 16 * sizeof(float)); } + memcpy(leftEye, hmdProjection, 16 * sizeof(float)); + memcpy(rightEye, hmdProjection, 16 * sizeof(float)); } void UpdateVRView(float* leftEye, float* rightEye) { diff --git a/Common/VR/VRRenderer.cpp b/Common/VR/VRRenderer.cpp index cbe69f2307..d06d12867e 100644 --- a/Common/VR/VRRenderer.cpp +++ b/Common/VR/VRRenderer.cpp @@ -305,34 +305,34 @@ bool VR_InitFrame( engine_t* engine ) { // Update matrices for (int matrix = 0; matrix < VR_MATRIX_COUNT; matrix++) { - if ((matrix == VR_PROJECTION_MATRIX_LEFT_EYE) || (matrix == VR_PROJECTION_MATRIX_RIGHT_EYE)) { + if (matrix == VR_PROJECTION_MATRIX) { float nearZ = VR_GetConfigFloat(VR_CONFIG_FOV_SCALE) / 200.0f; float tanAngleLeft = tanf(fov.angleLeft); float tanAngleRight = tanf(fov.angleRight); float tanAngleDown = tanf(fov.angleDown); float tanAngleUp = tanf(fov.angleUp); - float M[4][4]; - M[0][0] = 2 / (tanAngleRight - tanAngleLeft); - M[0][1] = 0; - M[0][2] = (tanAngleRight + tanAngleLeft) / (tanAngleRight - tanAngleLeft); - M[0][3] = 0; + float M[16]; + M[0] = 2 / (tanAngleRight - tanAngleLeft); + M[1] = 0; + M[2] = (tanAngleRight + tanAngleLeft) / (tanAngleRight - tanAngleLeft); + M[3] = 0; - M[1][0] = 0; - M[1][1] = 2 / (tanAngleUp - tanAngleDown); - M[1][2] = (tanAngleUp + tanAngleDown) / (tanAngleUp - tanAngleDown); - M[1][3] = 0; + M[4] = 0; + M[5] = 2 / (tanAngleUp - tanAngleDown); + M[6] = (tanAngleUp + tanAngleDown) / (tanAngleUp - tanAngleDown); + M[7] = 0; // place the far plane at infinity - M[2][0] = 0; - M[2][1] = 0; - M[2][2] = -1; - M[2][3] = -(nearZ + nearZ); + M[8] = 0; + M[9] = 0; + M[10] = -1; + M[11] = -(nearZ + nearZ); - M[3][0] = 0; - M[3][1] = 0; - M[3][2] = -1; - M[3][3] = 0; + M[12] = 0; + M[13] = 0; + M[14] = -1; + M[15]= = 0; memcpy(vrMatrix[matrix], M, sizeof(float) * 16); } else if ((matrix == VR_VIEW_MATRIX_LEFT_EYE) || (matrix == VR_VIEW_MATRIX_RIGHT_EYE)) { diff --git a/Common/VR/VRRenderer.h b/Common/VR/VRRenderer.h index 3600aec081..fed2a9acfc 100644 --- a/Common/VR/VRRenderer.h +++ b/Common/VR/VRRenderer.h @@ -37,8 +37,7 @@ enum VRConfigFloat { }; enum VRMatrix { - VR_PROJECTION_MATRIX_LEFT_EYE, - VR_PROJECTION_MATRIX_RIGHT_EYE, + VR_PROJECTION_MATRIX, VR_VIEW_MATRIX_LEFT_EYE, VR_VIEW_MATRIX_RIGHT_EYE, VR_MATRIX_COUNT From 520b92aa943c78a6cf68aee75cee75dde7d657a4 Mon Sep 17 00:00:00 2001 From: Lubos Date: Sun, 6 Nov 2022 21:45:47 +0100 Subject: [PATCH 3/9] OpenXR - Matrix indexing fixed --- Common/VR/VRRenderer.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Common/VR/VRRenderer.cpp b/Common/VR/VRRenderer.cpp index d06d12867e..ab63de0084 100644 --- a/Common/VR/VRRenderer.cpp +++ b/Common/VR/VRRenderer.cpp @@ -332,7 +332,7 @@ bool VR_InitFrame( engine_t* engine ) { M[12] = 0; M[13] = 0; M[14] = -1; - M[15]= = 0; + M[15] = 0; memcpy(vrMatrix[matrix], M, sizeof(float) * 16); } else if ((matrix == VR_VIEW_MATRIX_LEFT_EYE) || (matrix == VR_VIEW_MATRIX_RIGHT_EYE)) { @@ -381,25 +381,25 @@ bool VR_InitFrame( engine_t* engine ) { XrVector3f forward = {0.0f, 0.0f, VR_GetConfigFloat(VR_CONFIG_CAMERA_DISTANCE) * scale}; forward = XrQuaternionf_Rotate(invView.orientation, forward); forward = XrVector3f_ScalarMultiply(forward, vrConfig[VR_CONFIG_MIRROR_AXIS_Z] ? -1.0f : 1.0f); - M[12] += forward.x; - M[13] += forward.y; - M[14] += forward.z; + M[3] += forward.x; + M[7] += forward.y; + M[11] += forward.z; } if (fabsf(VR_GetConfigFloat(VR_CONFIG_CAMERA_HEIGHT)) > 0.0f) { XrVector3f up = {0.0f, -VR_GetConfigFloat(VR_CONFIG_CAMERA_HEIGHT) * scale, 0.0f}; up = XrQuaternionf_Rotate(invView.orientation, up); up = XrVector3f_ScalarMultiply(up, vrConfig[VR_CONFIG_MIRROR_AXIS_Y] ? -1.0f : 1.0f); - M[12] += up.x; - M[13] += up.y; - M[14] += up.z; + M[3] += up.x; + M[7] += up.y; + M[11] += up.z; } if (fabsf(VR_GetConfigFloat(VR_CONFIG_CAMERA_SIDE)) > 0.0f) { XrVector3f side = {-VR_GetConfigFloat(VR_CONFIG_CAMERA_SIDE) * scale, 0.0f, 0.0f}; side = XrQuaternionf_Rotate(invView.orientation, side); side = XrVector3f_ScalarMultiply(side, vrConfig[VR_CONFIG_MIRROR_AXIS_X] ? -1.0f : 1.0f); - M[12] += side.x; - M[13] += side.y; - M[14] += side.z; + M[3] += side.x; + M[7] += side.y; + M[11] += side.z; } if (vrConfig[VR_CONFIG_HAS_UNIT_SCALE] && (matrix == VR_VIEW_MATRIX_RIGHT_EYE)) { float dx = fabs(invViewTransform[1].position.x - invViewTransform[0].position.x); @@ -409,9 +409,9 @@ bool VR_InitFrame( engine_t* engine ) { XrVector3f separation = {ipd * scale, 0.0f, 0.0f}; separation = XrQuaternionf_Rotate(invView.orientation, separation); separation = XrVector3f_ScalarMultiply(separation, vrConfig[VR_CONFIG_MIRROR_AXIS_Z] ? -1.0f : 1.0f); - M[12] -= separation.x; - M[13] -= separation.y; - M[14] -= separation.z; + M[3] -= separation.x; + M[7] -= separation.y; + M[11] -= separation.z; } memcpy(vrMatrix[matrix], M, sizeof(float) * 16); } else { From cd54873edbd1236fef05e2f950ad0b687e7459bf Mon Sep 17 00:00:00 2001 From: Lubos Date: Sun, 6 Nov 2022 21:48:55 +0100 Subject: [PATCH 4/9] OpenXR - Simplify projection matrix creation --- Common/VR/VRRenderer.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/Common/VR/VRRenderer.cpp b/Common/VR/VRRenderer.cpp index ab63de0084..3a2ba7e6dd 100644 --- a/Common/VR/VRRenderer.cpp +++ b/Common/VR/VRRenderer.cpp @@ -312,27 +312,14 @@ bool VR_InitFrame( engine_t* engine ) { float tanAngleDown = tanf(fov.angleDown); float tanAngleUp = tanf(fov.angleUp); - float M[16]; + float M[16] = {}; M[0] = 2 / (tanAngleRight - tanAngleLeft); - M[1] = 0; M[2] = (tanAngleRight + tanAngleLeft) / (tanAngleRight - tanAngleLeft); - M[3] = 0; - - M[4] = 0; M[5] = 2 / (tanAngleUp - tanAngleDown); M[6] = (tanAngleUp + tanAngleDown) / (tanAngleUp - tanAngleDown); - M[7] = 0; - - // place the far plane at infinity - M[8] = 0; - M[9] = 0; M[10] = -1; M[11] = -(nearZ + nearZ); - - M[12] = 0; - M[13] = 0; M[14] = -1; - M[15] = 0; memcpy(vrMatrix[matrix], M, sizeof(float) * 16); } else if ((matrix == VR_VIEW_MATRIX_LEFT_EYE) || (matrix == VR_VIEW_MATRIX_RIGHT_EYE)) { From 460386e3444d5a2bfd1adc7c15bb3ad1c2a5cd39 Mon Sep 17 00:00:00 2001 From: Lubos Date: Sun, 6 Nov 2022 22:06:27 +0100 Subject: [PATCH 5/9] OpenXR - Move matrix calculation out of VRRenderer --- Common/VR/PPSSPPVR.cpp | 129 ++++++++++++++++++++++++++++++++++++++- Common/VR/VRRenderer.cpp | 110 +-------------------------------- Common/VR/VRRenderer.h | 10 +-- 3 files changed, 129 insertions(+), 120 deletions(-) diff --git a/Common/VR/PPSSPPVR.cpp b/Common/VR/PPSSPPVR.cpp index a548eb452f..5e1ad3c6d8 100644 --- a/Common/VR/PPSSPPVR.cpp +++ b/Common/VR/PPSSPPVR.cpp @@ -16,7 +16,15 @@ #include "Core/KeyMap.h" #include "Core/System.h" +enum VRMatrix { + VR_PROJECTION_MATRIX, + VR_VIEW_MATRIX_LEFT_EYE, + VR_VIEW_MATRIX_RIGHT_EYE, + VR_MATRIX_COUNT +}; + static long vrCompat[VR_COMPAT_MAX]; +static float vrMatrix[VR_MATRIX_COUNT][16]; /* ================================================================================ @@ -420,6 +428,121 @@ bool StartVRRender() { if (VR_InitFrame(VR_GetEngine())) { + // Get OpenXR view and fov + XrFovf fov = {}; + XrPosef invViewTransform[2]; + for (int eye = 0; eye < ovrMaxNumEyes; eye++) { + XrView view = VR_GetView(eye); + fov.angleLeft += view.fov.angleLeft / 2.0f; + fov.angleRight += view.fov.angleRight / 2.0f; + fov.angleUp += view.fov.angleUp / 2.0f; + fov.angleDown += view.fov.angleDown / 2.0f; + invViewTransform[eye] = view.pose; + } + + // Update matrices + for (int matrix = 0; matrix < VR_MATRIX_COUNT; matrix++) { + if (matrix == VR_PROJECTION_MATRIX) { + float nearZ = VR_GetConfigFloat(VR_CONFIG_FOV_SCALE) / 200.0f; + float tanAngleLeft = tanf(fov.angleLeft); + float tanAngleRight = tanf(fov.angleRight); + float tanAngleDown = tanf(fov.angleDown); + float tanAngleUp = tanf(fov.angleUp); + + float M[16] = {}; + M[0] = 2 / (tanAngleRight - tanAngleLeft); + M[2] = (tanAngleRight + tanAngleLeft) / (tanAngleRight - tanAngleLeft); + M[5] = 2 / (tanAngleUp - tanAngleDown); + M[6] = (tanAngleUp + tanAngleDown) / (tanAngleUp - tanAngleDown); + M[10] = -1; + M[11] = -(nearZ + nearZ); + M[14] = -1; + + memcpy(vrMatrix[matrix], M, sizeof(float) * 16); + } else if ((matrix == VR_VIEW_MATRIX_LEFT_EYE) || (matrix == VR_VIEW_MATRIX_RIGHT_EYE)) { + bool flatScreen = false; + XrPosef invView = invViewTransform[0]; + int vrMode = VR_GetConfig(VR_CONFIG_MODE); + if ((vrMode == VR_MODE_MONO_SCREEN) || (vrMode == VR_MODE_STEREO_SCREEN)) { + invView = XrPosef_Identity(); + flatScreen = true; + } + + // get axis mirroring configuration + float mx = VR_GetConfig(VR_CONFIG_MIRROR_PITCH) ? -1.0f : 1.0f; + float my = VR_GetConfig(VR_CONFIG_MIRROR_YAW) ? -1.0f : 1.0f; + float mz = VR_GetConfig(VR_CONFIG_MIRROR_ROLL) ? -1.0f : 1.0f; + + // ensure there is maximally one axis to mirror rotation + 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 - EPSILON) { + XrVector3f rotation = XrQuaternionf_ToEulerAngles(invView.orientation); + XrQuaternionf pitch = XrQuaternionf_CreateFromVectorAngle({1, 0, 0}, mx * ToRadians(rotation.x)); + XrQuaternionf yaw = XrQuaternionf_CreateFromVectorAngle({0, 1, 0}, my * ToRadians(rotation.y)); + XrQuaternionf roll = XrQuaternionf_CreateFromVectorAngle({0, 0, 1}, mz * ToRadians(rotation.z)); + invView.orientation = XrQuaternionf_Multiply(roll, XrQuaternionf_Multiply(pitch, yaw)); + } + + float M[16]; + XrQuaternionf_ToMatrix4f(&invView.orientation, M); + memcpy(&M, M, sizeof(float) * 16); + + float scale = VR_GetConfigFloat(VR_CONFIG_6DOF_SCALE); + if (!flatScreen && VR_GetConfig(VR_CONFIG_6DOF_ENABLED)) { + M[12] -= invViewTransform[0].position.x * (VR_GetConfig(VR_CONFIG_MIRROR_AXIS_X) ? -1.0f : 1.0f) * scale; + M[13] -= invViewTransform[0].position.y * (VR_GetConfig(VR_CONFIG_MIRROR_AXIS_Y) ? -1.0f : 1.0f) * scale; + M[14] -= invViewTransform[0].position.z * (VR_GetConfig(VR_CONFIG_MIRROR_AXIS_Z) ? -1.0f : 1.0f) * scale; + } + if (fabsf(VR_GetConfigFloat(VR_CONFIG_CAMERA_DISTANCE)) > 0.0f) { + XrVector3f forward = {0.0f, 0.0f, VR_GetConfigFloat(VR_CONFIG_CAMERA_DISTANCE) * scale}; + forward = XrQuaternionf_Rotate(invView.orientation, forward); + forward = XrVector3f_ScalarMultiply(forward, VR_GetConfig(VR_CONFIG_MIRROR_AXIS_Z) ? -1.0f : 1.0f); + M[3] += forward.x; + M[7] += forward.y; + M[11] += forward.z; + } + if (fabsf(VR_GetConfigFloat(VR_CONFIG_CAMERA_HEIGHT)) > 0.0f) { + XrVector3f up = {0.0f, -VR_GetConfigFloat(VR_CONFIG_CAMERA_HEIGHT) * scale, 0.0f}; + up = XrQuaternionf_Rotate(invView.orientation, up); + up = XrVector3f_ScalarMultiply(up, VR_GetConfig(VR_CONFIG_MIRROR_AXIS_Y) ? -1.0f : 1.0f); + M[3] += up.x; + M[7] += up.y; + M[11] += up.z; + } + if (fabsf(VR_GetConfigFloat(VR_CONFIG_CAMERA_SIDE)) > 0.0f) { + XrVector3f side = {-VR_GetConfigFloat(VR_CONFIG_CAMERA_SIDE) * scale, 0.0f, 0.0f}; + side = XrQuaternionf_Rotate(invView.orientation, side); + side = XrVector3f_ScalarMultiply(side, VR_GetConfig(VR_CONFIG_MIRROR_AXIS_X) ? -1.0f : 1.0f); + M[3] += side.x; + M[7] += side.y; + M[11] += side.z; + } + if (VR_GetConfig(VR_CONFIG_HAS_UNIT_SCALE) && (matrix == VR_VIEW_MATRIX_RIGHT_EYE)) { + float dx = fabs(invViewTransform[1].position.x - invViewTransform[0].position.x); + float dy = fabs(invViewTransform[1].position.y - invViewTransform[0].position.y); + float dz = fabs(invViewTransform[1].position.z - invViewTransform[0].position.z); + float ipd = sqrt(dx * dx + dy * dy + dz * dz); + XrVector3f separation = {ipd * scale, 0.0f, 0.0f}; + separation = XrQuaternionf_Rotate(invView.orientation, separation); + separation = XrVector3f_ScalarMultiply(separation, VR_GetConfig(VR_CONFIG_MIRROR_AXIS_Z) ? -1.0f : 1.0f); + M[3] -= separation.x; + M[7] -= separation.y; + M[11] -= separation.z; + } + memcpy(vrMatrix[matrix], M, sizeof(float) * 16); + } else { + assert(false); + } + } + // Decide if the scene is 3D or not if (g_Config.bEnableVR && !VR_GetConfig(VR_CONFIG_FORCE_2D) && (VR_GetConfig(VR_CONFIG_3D_GEOMETRY_COUNT) > 15)) { bool stereo = VR_GetConfig(VR_CONFIG_HAS_UNIT_SCALE) && g_Config.bEnableStereo; @@ -583,7 +706,7 @@ void UpdateVRParams(float* projMatrix) { } void UpdateVRProjection(float* projMatrix, float* leftEye, float* rightEye) { - float* hmdProjection = VR_GetMatrix(VR_PROJECTION_MATRIX); + float* hmdProjection = vrMatrix[VR_PROJECTION_MATRIX]; for (int i = 0; i < 16; i++) { if ((hmdProjection[i] > 0) != (projMatrix[i] > 0)) { hmdProjection[i] *= -1.0f; @@ -595,7 +718,7 @@ void UpdateVRProjection(float* projMatrix, float* leftEye, float* rightEye) { void UpdateVRView(float* leftEye, float* rightEye) { float* dst[] = {leftEye, rightEye}; - VRMatrix enums[] = {VR_VIEW_MATRIX_LEFT_EYE, VR_VIEW_MATRIX_RIGHT_EYE}; + float* matrix[] = {vrMatrix[VR_VIEW_MATRIX_LEFT_EYE], vrMatrix[VR_VIEW_MATRIX_RIGHT_EYE]}; for (int index = 0; index < 2; index++) { // Get view matrix from the game @@ -604,7 +727,7 @@ void UpdateVRView(float* leftEye, float* rightEye) { // Get view matrix from the headset Lin::Matrix4x4 hmdView = {}; - memcpy(hmdView.m, VR_GetMatrix(enums[index]), 16 * sizeof(float)); + memcpy(hmdView.m, matrix[index], 16 * sizeof(float)); // Combine the matrices Lin::Matrix4x4 renderView = hmdView * gameView; diff --git a/Common/VR/VRRenderer.cpp b/Common/VR/VRRenderer.cpp index 3a2ba7e6dd..a40d29f12a 100644 --- a/Common/VR/VRRenderer.cpp +++ b/Common/VR/VRRenderer.cpp @@ -16,12 +16,10 @@ XrPosef invViewTransform[2]; XrFrameState frameState = {}; bool initialized = false; bool stageSupported = false; -float vrMatrix[VR_MATRIX_COUNT][16]; int vrConfig[VR_CONFIG_MAX] = {}; float vrConfigFloat[VR_CONFIG_FLOAT_MAX] = {}; XrVector3f hmdorientation; -XrVector3f hmdposition; void VR_UpdateStageBounds(ovrApp* pappState) { XrExtent2Df stageBounds = {}; @@ -297,114 +295,10 @@ bool VR_InitFrame( engine_t* engine ) { // Update HMD and controllers hmdorientation = XrQuaternionf_ToEulerAngles(invViewTransform[0].orientation); - hmdposition = invViewTransform[0].position; IN_VRInputFrame(engine); engine->appState.LayerCount = 0; memset(engine->appState.Layers, 0, sizeof(ovrCompositorLayer_Union) * ovrMaxLayerCount); - - // Update matrices - for (int matrix = 0; matrix < VR_MATRIX_COUNT; matrix++) { - if (matrix == VR_PROJECTION_MATRIX) { - float nearZ = VR_GetConfigFloat(VR_CONFIG_FOV_SCALE) / 200.0f; - float tanAngleLeft = tanf(fov.angleLeft); - float tanAngleRight = tanf(fov.angleRight); - float tanAngleDown = tanf(fov.angleDown); - float tanAngleUp = tanf(fov.angleUp); - - float M[16] = {}; - M[0] = 2 / (tanAngleRight - tanAngleLeft); - M[2] = (tanAngleRight + tanAngleLeft) / (tanAngleRight - tanAngleLeft); - M[5] = 2 / (tanAngleUp - tanAngleDown); - M[6] = (tanAngleUp + tanAngleDown) / (tanAngleUp - tanAngleDown); - M[10] = -1; - M[11] = -(nearZ + nearZ); - M[14] = -1; - - memcpy(vrMatrix[matrix], M, sizeof(float) * 16); - } else if ((matrix == VR_VIEW_MATRIX_LEFT_EYE) || (matrix == VR_VIEW_MATRIX_RIGHT_EYE)) { - bool flatScreen = false; - XrPosef invView = invViewTransform[0]; - int vrMode = vrConfig[VR_CONFIG_MODE]; - if ((vrMode == VR_MODE_MONO_SCREEN) || (vrMode == VR_MODE_STEREO_SCREEN)) { - invView = XrPosef_Identity(); - flatScreen = true; - } - - // get axis mirroring configuration - float mx = vrConfig[VR_CONFIG_MIRROR_PITCH] ? -1.0f : 1.0f; - float my = vrConfig[VR_CONFIG_MIRROR_YAW] ? -1.0f : 1.0f; - float mz = vrConfig[VR_CONFIG_MIRROR_ROLL] ? -1.0f : 1.0f; - - // ensure there is maximally one axis to mirror rotation - 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 - EPSILON) { - XrVector3f rotation = XrQuaternionf_ToEulerAngles(invView.orientation); - XrQuaternionf pitch = XrQuaternionf_CreateFromVectorAngle({1, 0, 0}, mx * ToRadians(rotation.x)); - XrQuaternionf yaw = XrQuaternionf_CreateFromVectorAngle({0, 1, 0}, my * ToRadians(rotation.y)); - XrQuaternionf roll = XrQuaternionf_CreateFromVectorAngle({0, 0, 1}, mz * ToRadians(rotation.z)); - invView.orientation = XrQuaternionf_Multiply(roll, XrQuaternionf_Multiply(pitch, yaw)); - } - - float M[16]; - XrQuaternionf_ToMatrix4f(&invView.orientation, M); - memcpy(&M, M, sizeof(float) * 16); - - float scale = VR_GetConfigFloat(VR_CONFIG_6DOF_SCALE); - if (!flatScreen && vrConfig[VR_CONFIG_6DOF_ENABLED]) { - M[12] -= hmdposition.x * (vrConfig[VR_CONFIG_MIRROR_AXIS_X] ? -1.0f : 1.0f) * scale; - M[13] -= hmdposition.y * (vrConfig[VR_CONFIG_MIRROR_AXIS_Y] ? -1.0f : 1.0f) * scale; - M[14] -= hmdposition.z * (vrConfig[VR_CONFIG_MIRROR_AXIS_Z] ? -1.0f : 1.0f) * scale; - } - if (fabsf(VR_GetConfigFloat(VR_CONFIG_CAMERA_DISTANCE)) > 0.0f) { - XrVector3f forward = {0.0f, 0.0f, VR_GetConfigFloat(VR_CONFIG_CAMERA_DISTANCE) * scale}; - forward = XrQuaternionf_Rotate(invView.orientation, forward); - forward = XrVector3f_ScalarMultiply(forward, vrConfig[VR_CONFIG_MIRROR_AXIS_Z] ? -1.0f : 1.0f); - M[3] += forward.x; - M[7] += forward.y; - M[11] += forward.z; - } - if (fabsf(VR_GetConfigFloat(VR_CONFIG_CAMERA_HEIGHT)) > 0.0f) { - XrVector3f up = {0.0f, -VR_GetConfigFloat(VR_CONFIG_CAMERA_HEIGHT) * scale, 0.0f}; - up = XrQuaternionf_Rotate(invView.orientation, up); - up = XrVector3f_ScalarMultiply(up, vrConfig[VR_CONFIG_MIRROR_AXIS_Y] ? -1.0f : 1.0f); - M[3] += up.x; - M[7] += up.y; - M[11] += up.z; - } - if (fabsf(VR_GetConfigFloat(VR_CONFIG_CAMERA_SIDE)) > 0.0f) { - XrVector3f side = {-VR_GetConfigFloat(VR_CONFIG_CAMERA_SIDE) * scale, 0.0f, 0.0f}; - side = XrQuaternionf_Rotate(invView.orientation, side); - side = XrVector3f_ScalarMultiply(side, vrConfig[VR_CONFIG_MIRROR_AXIS_X] ? -1.0f : 1.0f); - M[3] += side.x; - M[7] += side.y; - M[11] += side.z; - } - if (vrConfig[VR_CONFIG_HAS_UNIT_SCALE] && (matrix == VR_VIEW_MATRIX_RIGHT_EYE)) { - float dx = fabs(invViewTransform[1].position.x - invViewTransform[0].position.x); - float dy = fabs(invViewTransform[1].position.y - invViewTransform[0].position.y); - float dz = fabs(invViewTransform[1].position.z - invViewTransform[0].position.z); - float ipd = sqrt(dx * dx + dy * dy + dz * dz); - XrVector3f separation = {ipd * scale, 0.0f, 0.0f}; - separation = XrQuaternionf_Rotate(invView.orientation, separation); - separation = XrVector3f_ScalarMultiply(separation, vrConfig[VR_CONFIG_MIRROR_AXIS_Z] ? -1.0f : 1.0f); - M[3] -= separation.x; - M[7] -= separation.y; - M[11] -= separation.z; - } - memcpy(vrMatrix[matrix], M, sizeof(float) * 16); - } else { - assert(false); - } - } return true; } @@ -568,6 +462,6 @@ void* VR_BindFramebuffer(engine_t *engine) { return ovrFramebuffer_SetCurrent(&engine->appState.Renderer.FrameBuffer[fboIndex]); } -float* VR_GetMatrix( VRMatrix matrix ) { - return vrMatrix[matrix]; +XrView VR_GetView(int eye) { + return projections[eye]; } diff --git a/Common/VR/VRRenderer.h b/Common/VR/VRRenderer.h index fed2a9acfc..d05e4b90b1 100644 --- a/Common/VR/VRRenderer.h +++ b/Common/VR/VRRenderer.h @@ -36,13 +36,6 @@ enum VRConfigFloat { VR_CONFIG_FLOAT_MAX }; -enum VRMatrix { - VR_PROJECTION_MATRIX, - VR_VIEW_MATRIX_LEFT_EYE, - VR_VIEW_MATRIX_RIGHT_EYE, - VR_MATRIX_COUNT -}; - enum VRMode { VR_MODE_MONO_SCREEN, VR_MODE_STEREO_SCREEN, @@ -61,9 +54,8 @@ void VR_FinishFrame( engine_t* engine ); int VR_GetConfig( VRConfig config ); void VR_SetConfig( VRConfig config, int value); - float VR_GetConfigFloat( VRConfigFloat config ); void VR_SetConfigFloat( VRConfigFloat config, float value ); void* VR_BindFramebuffer(engine_t *engine); -float* VR_GetMatrix( VRMatrix matrix ); +XrView VR_GetView(int eye); From c58359a3b39ffd1380306c22f2afa4445cd0a928 Mon Sep 17 00:00:00 2001 From: Lubos Date: Sun, 6 Nov 2022 22:30:35 +0100 Subject: [PATCH 6/9] OpenXR - Move configs out of VRRenderer --- Common/VR/PPSSPPVR.cpp | 137 ++++++++++++++++++++++------------------- Common/VR/VRRenderer.h | 16 +---- 2 files changed, 76 insertions(+), 77 deletions(-) diff --git a/Common/VR/PPSSPPVR.cpp b/Common/VR/PPSSPPVR.cpp index 5e1ad3c6d8..3b46301036 100644 --- a/Common/VR/PPSSPPVR.cpp +++ b/Common/VR/PPSSPPVR.cpp @@ -23,8 +23,23 @@ enum VRMatrix { VR_MATRIX_COUNT }; +enum VRMirroring { + VR_MIRRORING_UPDATED, + VR_MIRRORING_AXIS_X, + VR_MIRRORING_AXIS_Y, + VR_MIRRORING_AXIS_Z, + VR_MIRRORING_PITCH, + VR_MIRRORING_YAW, + VR_MIRRORING_ROLL, + VR_MIRRORING_COUNT +}; + +static int vr3DGeometryCount = 0; +static bool vrCameraControl = false; +static bool vrForce2D = false; static long vrCompat[VR_COMPAT_MAX]; static float vrMatrix[VR_MATRIX_COUNT][16]; +static bool vrMirroring[VR_MIRRORING_COUNT]; /* ================================================================================ @@ -182,7 +197,6 @@ void UpdateVRInput(bool(*NativeKey)(const KeyInput &key), bool(*NativeTouch)(con KeyInput keyInput = {}; for (int j = 0; j < 2; j++) { int status = IN_VRGetButtonState(j); - bool cameraControl = VR_GetConfig(VR_CONFIG_CAMERA_CONTROL); for (ButtonMapping& m : controllerMapping[j]) { //check if camera key was pressed @@ -208,14 +222,14 @@ void UpdateVRInput(bool(*NativeKey)(const KeyInput &key), bool(*NativeTouch)(con if (pressed && haptics) { INVR_Vibrate(100, j, 1000); } - if (!cameraControl || cameraKey) { + if (!vrCameraControl || cameraKey) { NativeKey(keyInput); } m.pressed = pressed; m.repeat = 0; } else if (pressed && (m.repeat > 30)) { keyInput.flags |= KEY_IS_REPEAT; - if (!cameraControl || cameraKey) { + if (!vrCameraControl || cameraKey) { NativeKey(keyInput); } m.repeat = 0; @@ -331,11 +345,11 @@ void UpdateVRSpecialKeys(const KeyInput &key) { for (int& nativeKey : nativeKeys) { // adjust camera parameters if (nativeKey == VIRTKEY_VR_CAMERA_ADJUST) { - VR_SetConfig(VR_CONFIG_CAMERA_CONTROL, key.flags & KEY_DOWN); + vrCameraControl = key.flags & KEY_DOWN; } // force 2D rendering else if (nativeKey == CTRL_SCREEN) { - VR_SetConfig(VR_CONFIG_FORCE_2D, key.flags & KEY_DOWN); + vrForce2D = key.flags & KEY_DOWN; } } } @@ -440,10 +454,18 @@ bool StartVRRender() { invViewTransform[eye] = view.pose; } + // Get 6DoF scale + float scale = 1.0f; + bool hasUnitScale = false; + if (PSP_CoreParameter().compat.vrCompat().UnitsPerMeter > 0) { + scale = PSP_CoreParameter().compat.vrCompat().UnitsPerMeter; + hasUnitScale = true; + } + // Update matrices for (int matrix = 0; matrix < VR_MATRIX_COUNT; matrix++) { if (matrix == VR_PROJECTION_MATRIX) { - float nearZ = VR_GetConfigFloat(VR_CONFIG_FOV_SCALE) / 200.0f; + float nearZ = g_Config.fFieldOfViewPercentage / 200.0f; float tanAngleLeft = tanf(fov.angleLeft); float tanAngleRight = tanf(fov.angleRight); float tanAngleDown = tanf(fov.angleDown); @@ -469,9 +491,9 @@ bool StartVRRender() { } // get axis mirroring configuration - float mx = VR_GetConfig(VR_CONFIG_MIRROR_PITCH) ? -1.0f : 1.0f; - float my = VR_GetConfig(VR_CONFIG_MIRROR_YAW) ? -1.0f : 1.0f; - float mz = VR_GetConfig(VR_CONFIG_MIRROR_ROLL) ? -1.0f : 1.0f; + float mx = vrMirroring[VR_MIRRORING_PITCH] ? -1.0f : 1.0f; + float my = vrMirroring[VR_MIRRORING_YAW] ? -1.0f : 1.0f; + float mz = vrMirroring[VR_MIRRORING_ROLL] ? -1.0f : 1.0f; // ensure there is maximally one axis to mirror rotation if (mx + my + mz < 0) { @@ -495,44 +517,48 @@ bool StartVRRender() { XrQuaternionf_ToMatrix4f(&invView.orientation, M); memcpy(&M, M, sizeof(float) * 16); - float scale = VR_GetConfigFloat(VR_CONFIG_6DOF_SCALE); - if (!flatScreen && VR_GetConfig(VR_CONFIG_6DOF_ENABLED)) { - M[12] -= invViewTransform[0].position.x * (VR_GetConfig(VR_CONFIG_MIRROR_AXIS_X) ? -1.0f : 1.0f) * scale; - M[13] -= invViewTransform[0].position.y * (VR_GetConfig(VR_CONFIG_MIRROR_AXIS_Y) ? -1.0f : 1.0f) * scale; - M[14] -= invViewTransform[0].position.z * (VR_GetConfig(VR_CONFIG_MIRROR_AXIS_Z) ? -1.0f : 1.0f) * scale; + // Apply 6Dof head movement + if (!flatScreen && g_Config.bEnable6DoF) { + M[3] -= invViewTransform[0].position.x * (vrMirroring[VR_MIRRORING_AXIS_X] ? -1.0f : 1.0f) * scale; + M[7] -= invViewTransform[0].position.y * (vrMirroring[VR_MIRRORING_AXIS_Y] ? -1.0f : 1.0f) * scale; + M[11] -= invViewTransform[0].position.z * (vrMirroring[VR_MIRRORING_AXIS_Z] ? -1.0f : 1.0f) * scale; } - if (fabsf(VR_GetConfigFloat(VR_CONFIG_CAMERA_DISTANCE)) > 0.0f) { - XrVector3f forward = {0.0f, 0.0f, VR_GetConfigFloat(VR_CONFIG_CAMERA_DISTANCE) * scale}; + // Camera adjust - distance + if (fabsf(g_Config.fCameraDistance) > 0.0f) { + XrVector3f forward = {0.0f, 0.0f, g_Config.fCameraDistance * scale}; forward = XrQuaternionf_Rotate(invView.orientation, forward); - forward = XrVector3f_ScalarMultiply(forward, VR_GetConfig(VR_CONFIG_MIRROR_AXIS_Z) ? -1.0f : 1.0f); + forward = XrVector3f_ScalarMultiply(forward, vrMirroring[VR_MIRRORING_AXIS_Z] ? -1.0f : 1.0f); M[3] += forward.x; M[7] += forward.y; M[11] += forward.z; } - if (fabsf(VR_GetConfigFloat(VR_CONFIG_CAMERA_HEIGHT)) > 0.0f) { - XrVector3f up = {0.0f, -VR_GetConfigFloat(VR_CONFIG_CAMERA_HEIGHT) * scale, 0.0f}; + // Camera adjust - height + if (fabsf(g_Config.fCameraHeight) > 0.0f) { + XrVector3f up = {0.0f, -g_Config.fCameraHeight * scale, 0.0f}; up = XrQuaternionf_Rotate(invView.orientation, up); - up = XrVector3f_ScalarMultiply(up, VR_GetConfig(VR_CONFIG_MIRROR_AXIS_Y) ? -1.0f : 1.0f); + up = XrVector3f_ScalarMultiply(up, vrMirroring[VR_MIRRORING_AXIS_Y] ? -1.0f : 1.0f); M[3] += up.x; M[7] += up.y; M[11] += up.z; } - if (fabsf(VR_GetConfigFloat(VR_CONFIG_CAMERA_SIDE)) > 0.0f) { - XrVector3f side = {-VR_GetConfigFloat(VR_CONFIG_CAMERA_SIDE) * scale, 0.0f, 0.0f}; + // Camera adjust - side + if (fabsf(g_Config.fCameraSide) > 0.0f) { + XrVector3f side = {-g_Config.fCameraSide * scale, 0.0f, 0.0f}; side = XrQuaternionf_Rotate(invView.orientation, side); - side = XrVector3f_ScalarMultiply(side, VR_GetConfig(VR_CONFIG_MIRROR_AXIS_X) ? -1.0f : 1.0f); + side = XrVector3f_ScalarMultiply(side, vrMirroring[VR_MIRRORING_AXIS_X] ? -1.0f : 1.0f); M[3] += side.x; M[7] += side.y; M[11] += side.z; } - if (VR_GetConfig(VR_CONFIG_HAS_UNIT_SCALE) && (matrix == VR_VIEW_MATRIX_RIGHT_EYE)) { + // Stereoscopy + if (hasUnitScale && (matrix == VR_VIEW_MATRIX_RIGHT_EYE)) { float dx = fabs(invViewTransform[1].position.x - invViewTransform[0].position.x); float dy = fabs(invViewTransform[1].position.y - invViewTransform[0].position.y); float dz = fabs(invViewTransform[1].position.z - invViewTransform[0].position.z); float ipd = sqrt(dx * dx + dy * dy + dz * dz); XrVector3f separation = {ipd * scale, 0.0f, 0.0f}; separation = XrQuaternionf_Rotate(invView.orientation, separation); - separation = XrVector3f_ScalarMultiply(separation, VR_GetConfig(VR_CONFIG_MIRROR_AXIS_Z) ? -1.0f : 1.0f); + separation = XrVector3f_ScalarMultiply(separation, vrMirroring[VR_MIRRORING_AXIS_Z] ? -1.0f : 1.0f); M[3] -= separation.x; M[7] -= separation.y; M[11] -= separation.z; @@ -544,19 +570,19 @@ bool StartVRRender() { } // Decide if the scene is 3D or not - if (g_Config.bEnableVR && !VR_GetConfig(VR_CONFIG_FORCE_2D) && (VR_GetConfig(VR_CONFIG_3D_GEOMETRY_COUNT) > 15)) { - bool stereo = VR_GetConfig(VR_CONFIG_HAS_UNIT_SCALE) && g_Config.bEnableStereo; + if (g_Config.bEnableVR && !vrForce2D && (vr3DGeometryCount > 15)) { + bool stereo = hasUnitScale && g_Config.bEnableStereo; VR_SetConfig(VR_CONFIG_MODE, stereo ? VR_MODE_STEREO_6DOF : VR_MODE_MONO_6DOF); } else { VR_SetConfig(VR_CONFIG_MODE, g_Config.bEnableStereo ? VR_MODE_STEREO_SCREEN : VR_MODE_MONO_SCREEN); } - VR_SetConfig(VR_CONFIG_3D_GEOMETRY_COUNT, VR_GetConfig(VR_CONFIG_3D_GEOMETRY_COUNT) / 2); + vr3DGeometryCount /= 2; // Set compatibility vrCompat[VR_COMPAT_SKYPLANE] = PSP_CoreParameter().compat.vrCompat().Skyplane; // Camera control - if (VR_GetConfig(VR_CONFIG_CAMERA_CONTROL)) { + if (vrCameraControl) { //left joystick controls height and side float height = g_Config.fCameraHeight; float side = g_Config.fCameraSide; @@ -590,13 +616,8 @@ bool StartVRRender() { // Set customizations __DisplaySetFramerate(g_Config.bForce72Hz ? 72 : 60); - VR_SetConfig(VR_CONFIG_6DOF_ENABLED, g_Config.bEnable6DoF); - VR_SetConfigFloat(VR_CONFIG_CAMERA_DISTANCE, g_Config.fCameraDistance); - VR_SetConfigFloat(VR_CONFIG_CAMERA_HEIGHT, g_Config.fCameraHeight); - VR_SetConfigFloat(VR_CONFIG_CAMERA_SIDE, g_Config.fCameraSide); VR_SetConfigFloat(VR_CONFIG_CANVAS_DISTANCE, g_Config.fCanvasDistance); - VR_SetConfigFloat(VR_CONFIG_FOV_SCALE, g_Config.fFieldOfViewPercentage); - VR_SetConfig(VR_CONFIG_MIRROR_UPDATED, false); + vrMirroring[VR_MIRRORING_UPDATED] = false; return true; } return false; @@ -662,7 +683,7 @@ bool Is2DVRObject(float* projMatrix, bool ortho) { // Update 3D geometry count if (!identity && !ortho) { - VR_SetConfig(VR_CONFIG_3D_GEOMETRY_COUNT, VR_GetConfig(VR_CONFIG_3D_GEOMETRY_COUNT) + 1); + vr3DGeometryCount++; } return identity; } @@ -670,39 +691,29 @@ bool Is2DVRObject(float* projMatrix, bool ortho) { void UpdateVRParams(float* projMatrix) { // Set mirroring of axes - if (!VR_GetConfig(VR_CONFIG_MIRROR_UPDATED)) { - VR_SetConfig(VR_CONFIG_MIRROR_UPDATED, true); - VR_SetConfig(VR_CONFIG_MIRROR_AXIS_X, projMatrix[0] < 0); - VR_SetConfig(VR_CONFIG_MIRROR_AXIS_Y, projMatrix[5] < 0); - VR_SetConfig(VR_CONFIG_MIRROR_AXIS_Z, projMatrix[10] > 0); + if (!vrMirroring[VR_MIRRORING_UPDATED]) { + vrMirroring[VR_MIRRORING_UPDATED] = true; + vrMirroring[VR_MIRRORING_AXIS_X] = projMatrix[0] < 0; + vrMirroring[VR_MIRRORING_AXIS_Y] = projMatrix[5] < 0; + vrMirroring[VR_MIRRORING_AXIS_Z] = projMatrix[10] > 0; if ((projMatrix[0] < 0) && (projMatrix[10] < 0)) { //e.g. Dante's inferno - VR_SetConfig(VR_CONFIG_MIRROR_PITCH, true); - VR_SetConfig(VR_CONFIG_MIRROR_YAW, true); - VR_SetConfig(VR_CONFIG_MIRROR_ROLL, false); + vrMirroring[VR_MIRRORING_PITCH] = true; + vrMirroring[VR_MIRRORING_YAW] = true; + vrMirroring[VR_MIRRORING_ROLL] = false; } else if (projMatrix[10] < 0) { //e.g. GTA - Liberty city - VR_SetConfig(VR_CONFIG_MIRROR_PITCH, false); - VR_SetConfig(VR_CONFIG_MIRROR_YAW, false); - VR_SetConfig(VR_CONFIG_MIRROR_ROLL, false); + vrMirroring[VR_MIRRORING_PITCH] = false; + vrMirroring[VR_MIRRORING_YAW] = false; + vrMirroring[VR_MIRRORING_ROLL] = false; } else if (projMatrix[5] < 0) { //e.g. PES 2014 - VR_SetConfig(VR_CONFIG_MIRROR_PITCH, true); - VR_SetConfig(VR_CONFIG_MIRROR_YAW, true); - VR_SetConfig(VR_CONFIG_MIRROR_ROLL, false); + vrMirroring[VR_MIRRORING_PITCH] = true; + vrMirroring[VR_MIRRORING_YAW] = true; + vrMirroring[VR_MIRRORING_ROLL] = false; } else { //e.g. Lego Pirates - VR_SetConfig(VR_CONFIG_MIRROR_PITCH, false); - VR_SetConfig(VR_CONFIG_MIRROR_YAW, true); - VR_SetConfig(VR_CONFIG_MIRROR_ROLL, true); + vrMirroring[VR_MIRRORING_PITCH] = false; + vrMirroring[VR_MIRRORING_YAW] = true; + vrMirroring[VR_MIRRORING_ROLL] = true; } } - - // Set 6DoF scale - float scale = 1.0f; - if (PSP_CoreParameter().compat.vrCompat().UnitsPerMeter > 0) { - scale = PSP_CoreParameter().compat.vrCompat().UnitsPerMeter; - VR_SetConfig(VR_CONFIG_HAS_UNIT_SCALE, true); - } else { - VR_SetConfig(VR_CONFIG_HAS_UNIT_SCALE, false); - } - VR_SetConfigFloat(VR_CONFIG_6DOF_SCALE, scale); } void UpdateVRProjection(float* projMatrix, float* leftEye, float* rightEye) { diff --git a/Common/VR/VRRenderer.h b/Common/VR/VRRenderer.h index d05e4b90b1..dcd57f1f4b 100644 --- a/Common/VR/VRRenderer.h +++ b/Common/VR/VRRenderer.h @@ -5,14 +5,7 @@ enum VRConfig { //switching between 2D and 3D - VR_CONFIG_MODE, VR_CONFIG_3D_GEOMETRY_COUNT, VR_CONFIG_FORCE_2D, - //camera setup - VR_CONFIG_CAMERA_CONTROL, - VR_CONFIG_HAS_UNIT_SCALE, - //6DoF - VR_CONFIG_6DOF_ENABLED, VR_CONFIG_MIRROR_UPDATED, - 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_MODE, //mouse cursor VR_CONFIG_MOUSE_SIZE, VR_CONFIG_MOUSE_X, VR_CONFIG_MOUSE_Y, //viewport setup @@ -25,13 +18,8 @@ enum VRConfig { }; enum VRConfigFloat { - // 6dof - VR_CONFIG_6DOF_SCALE, - // camera setup - VR_CONFIG_FOV_SCALE, VR_CONFIG_CAMERA_DISTANCE, - VR_CONFIG_CAMERA_HEIGHT, VR_CONFIG_CAMERA_SIDE, VR_CONFIG_CANVAS_DISTANCE, // 2D canvas positioning - VR_CONFIG_MENU_PITCH, VR_CONFIG_MENU_YAW, VR_CONFIG_RECENTER_YAW, + VR_CONFIG_CANVAS_DISTANCE, VR_CONFIG_MENU_PITCH, VR_CONFIG_MENU_YAW, VR_CONFIG_RECENTER_YAW, VR_CONFIG_FLOAT_MAX }; From e96b9b4649b71fb2ba6811b1880cc8763319c587 Mon Sep 17 00:00:00 2001 From: Lubos Date: Sun, 6 Nov 2022 22:38:15 +0100 Subject: [PATCH 7/9] Remove unnecessary assert --- Common/VR/PPSSPPVR.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Common/VR/PPSSPPVR.cpp b/Common/VR/PPSSPPVR.cpp index 3b46301036..eb011c6c07 100644 --- a/Common/VR/PPSSPPVR.cpp +++ b/Common/VR/PPSSPPVR.cpp @@ -564,8 +564,6 @@ bool StartVRRender() { M[11] -= separation.z; } memcpy(vrMatrix[matrix], M, sizeof(float) * 16); - } else { - assert(false); } } From 73ccff9ba00cdc3d3de5a83a438d36aec017a787 Mon Sep 17 00:00:00 2001 From: Lubos Date: Mon, 7 Nov 2022 16:28:41 +0100 Subject: [PATCH 8/9] Restore assert --- Common/VR/PPSSPPVR.cpp | 2 ++ Common/VR/VRBase.h | 1 + Common/VR/VRRenderer.cpp | 1 - 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Common/VR/PPSSPPVR.cpp b/Common/VR/PPSSPPVR.cpp index eb011c6c07..3b46301036 100644 --- a/Common/VR/PPSSPPVR.cpp +++ b/Common/VR/PPSSPPVR.cpp @@ -564,6 +564,8 @@ bool StartVRRender() { M[11] -= separation.z; } memcpy(vrMatrix[matrix], M, sizeof(float) * 16); + } else { + assert(false); } } diff --git a/Common/VR/VRBase.h b/Common/VR/VRBase.h index 34e52908d4..395858b136 100644 --- a/Common/VR/VRBase.h +++ b/Common/VR/VRBase.h @@ -14,6 +14,7 @@ #define _USE_MATH_DEFINES #include +#include #ifdef ANDROID diff --git a/Common/VR/VRRenderer.cpp b/Common/VR/VRRenderer.cpp index a40d29f12a..78133a26a2 100644 --- a/Common/VR/VRRenderer.cpp +++ b/Common/VR/VRRenderer.cpp @@ -6,7 +6,6 @@ #include "VRRenderer.h" #include "OpenXRLoader.h" -#include #include #include From 90d117ce7199bbddeaf397beff6aac5651ef5f65 Mon Sep 17 00:00:00 2001 From: Lubos Date: Mon, 7 Nov 2022 16:46:10 +0100 Subject: [PATCH 9/9] OpenXR - Keep status of PSP keys --- Common/VR/PPSSPPVR.cpp | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/Common/VR/PPSSPPVR.cpp b/Common/VR/PPSSPPVR.cpp index 3b46301036..73fb91f6aa 100644 --- a/Common/VR/PPSSPPVR.cpp +++ b/Common/VR/PPSSPPVR.cpp @@ -34,9 +34,9 @@ enum VRMirroring { VR_MIRRORING_COUNT }; +static std::map pspKeys; + static int vr3DGeometryCount = 0; -static bool vrCameraControl = false; -static bool vrForce2D = false; static long vrCompat[VR_COMPAT_MAX]; static float vrMatrix[VR_MATRIX_COUNT][16]; static bool vrMirroring[VR_MIRRORING_COUNT]; @@ -222,14 +222,14 @@ void UpdateVRInput(bool(*NativeKey)(const KeyInput &key), bool(*NativeTouch)(con if (pressed && haptics) { INVR_Vibrate(100, j, 1000); } - if (!vrCameraControl || cameraKey) { + if (!pspKeys[VIRTKEY_VR_CAMERA_ADJUST] || cameraKey) { NativeKey(keyInput); } m.pressed = pressed; m.repeat = 0; } else if (pressed && (m.repeat > 30)) { keyInput.flags |= KEY_IS_REPEAT; - if (!vrCameraControl || cameraKey) { + if (!pspKeys[VIRTKEY_VR_CAMERA_ADJUST] || cameraKey) { NativeKey(keyInput); } m.repeat = 0; @@ -343,14 +343,7 @@ void UpdateVRSpecialKeys(const KeyInput &key) { std::vector nativeKeys; if (KeyMap::KeyToPspButton(key.deviceId, key.keyCode, &nativeKeys)) { for (int& nativeKey : nativeKeys) { - // adjust camera parameters - if (nativeKey == VIRTKEY_VR_CAMERA_ADJUST) { - vrCameraControl = key.flags & KEY_DOWN; - } - // force 2D rendering - else if (nativeKey == CTRL_SCREEN) { - vrForce2D = key.flags & KEY_DOWN; - } + pspKeys[nativeKey] = key.flags & KEY_DOWN; } } } @@ -570,7 +563,7 @@ bool StartVRRender() { } // Decide if the scene is 3D or not - if (g_Config.bEnableVR && !vrForce2D && (vr3DGeometryCount > 15)) { + if (g_Config.bEnableVR && !pspKeys[CTRL_SCREEN] && (vr3DGeometryCount > 15)) { bool stereo = hasUnitScale && g_Config.bEnableStereo; VR_SetConfig(VR_CONFIG_MODE, stereo ? VR_MODE_STEREO_6DOF : VR_MODE_MONO_6DOF); } else { @@ -582,7 +575,7 @@ bool StartVRRender() { vrCompat[VR_COMPAT_SKYPLANE] = PSP_CoreParameter().compat.vrCompat().Skyplane; // Camera control - if (vrCameraControl) { + if (pspKeys[VIRTKEY_VR_CAMERA_ADJUST]) { //left joystick controls height and side float height = g_Config.fCameraHeight; float side = g_Config.fCameraSide;