From 637bb57bc6bdcf5339b385010e3e2b3da7664758 Mon Sep 17 00:00:00 2001 From: Lubos Date: Sun, 6 Nov 2022 20:42:28 +0100 Subject: [PATCH] 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 );