Skip to content

Commit

Permalink
Merge pull request #19127 from lvonasek/feature-openxr-projection
Browse files Browse the repository at this point in the history
OpenXR - Projection matrix (camera issue) fixed
  • Loading branch information
hrydgard committed May 10, 2024
2 parents b4755e9 + e76a5b1 commit ad541f2
Show file tree
Hide file tree
Showing 50 changed files with 151 additions and 20 deletions.
69 changes: 49 additions & 20 deletions Common/VR/PPSSPPVR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@
#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
};

enum VRMirroring {
VR_MIRRORING_AXIS_X,
VR_MIRRORING_AXIS_Y,
Expand All @@ -44,10 +51,9 @@ static int vr3DGeometryCount = 0;
static long vrCompat[VR_COMPAT_MAX];
static bool vrFlatForced = false;
static bool vrFlatGame = false;
static double vrFov[2] = {};
static float vrMatrix[VR_MATRIX_COUNT][16];
static bool vrMirroring[VR_MIRRORING_COUNT];
static int vrMirroringVariant = 0;
static float vrViewMatrix[2][16];
static XrView vrView[2];

static void (*cbNativeAxis)(const AxisInput *axis, size_t count);
Expand Down Expand Up @@ -636,16 +642,29 @@ bool StartVRRender() {
}
UpdateVRViewMatrices();

// Calculate field of view
// Update projection matrix
XrFovf fov = {};
for (auto & eye : vrView) {
fov.angleLeft += eye.fov.angleLeft / 2.0f;
fov.angleRight += eye.fov.angleRight / 2.0f;
fov.angleUp += eye.fov.angleUp / 2.0f;
fov.angleDown += eye.fov.angleDown / 2.0f;
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
fov.angleLeft += vrView[eye].fov.angleLeft / 2.0f;
fov.angleRight += vrView[eye].fov.angleRight / 2.0f;
fov.angleUp += vrView[eye].fov.angleUp / 2.0f;
fov.angleDown += vrView[eye].fov.angleDown / 2.0f;
}
vrFov[0] = 2.0 / (tan(fov.angleRight) - tan(fov.angleLeft));
vrFov[1] = 2.0 / (tan(fov.angleUp) - tan(fov.angleDown));
float nearZ = 0.01f;
float fovHack = g_Config.fFieldOfViewPercentage / 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[5] = 2 / (tanAngleUp - tanAngleDown);
M[8] = (tanAngleRight + tanAngleLeft) / (tanAngleRight - tanAngleLeft);
M[9] = (tanAngleUp + tanAngleDown) / (tanAngleUp - tanAngleDown);
M[10] = -1;
M[11] = -(fovHack + fovHack);
M[14] = -(nearZ + nearZ);
memcpy(vrMatrix[VR_PROJECTION_MATRIX], M, sizeof(float) * 16);

// Decide if the scene is 3D or not
VR_SetConfigFloat(VR_CONFIG_CANVAS_ASPECT, 480.0f / 272.0f);
Expand Down Expand Up @@ -790,16 +809,26 @@ void UpdateVRParams(float* projMatrix) {
}

void UpdateVRProjection(float* projMatrix, float* leftEye, float* rightEye) {
float hmdProjection[16];
memcpy(hmdProjection, projMatrix, 16 * sizeof(float));
hmdProjection[0] = vrFov[0];
hmdProjection[5] = vrFov[1];
memcpy(leftEye, hmdProjection, 16 * sizeof(float));
memcpy(rightEye, hmdProjection, 16 * sizeof(float));
float output[16];
for (int i = 0; i < 16; i++) {
if (PSP_CoreParameter().compat.vrCompat().ProjectionHack && ((i == 8) || (i == 9))) {
output[i] = 0;
} else if (fabs(projMatrix[i]) > 0) {
output[i] = vrMatrix[VR_PROJECTION_MATRIX][i];
if ((output[i] > 0) != (projMatrix[i] > 0)) {
output[i] *= -1.0f;
}
} else {
output[i] = 0;
}
}
memcpy(leftEye, output, 16 * sizeof(float));
memcpy(rightEye, output, 16 * sizeof(float));
}

void UpdateVRView(float* leftEye, float* rightEye) {
float* dst[] = {leftEye, rightEye};
float* matrix[] = {vrMatrix[VR_VIEW_MATRIX_LEFT_EYE], vrMatrix[VR_VIEW_MATRIX_RIGHT_EYE]};
for (int index = 0; index < 2; index++) {

// Validate the view matrix
Expand All @@ -813,7 +842,7 @@ void UpdateVRView(float* leftEye, float* rightEye) {

// Get view matrix from the headset
Lin::Matrix4x4 hmdView = {};
memcpy(hmdView.m, vrViewMatrix[index], 16 * sizeof(float));
memcpy(hmdView.m, matrix[index], 16 * sizeof(float));

// Combine the matrices
Lin::Matrix4x4 renderView = hmdView * gameView;
Expand Down Expand Up @@ -922,12 +951,12 @@ void UpdateVRViewMatrices() {
M[11] += side.z;
}

for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
for (int matrix = VR_VIEW_MATRIX_LEFT_EYE; matrix <= VR_VIEW_MATRIX_RIGHT_EYE; matrix++) {

// Stereoscopy
bool vrStereo = !PSP_CoreParameter().compat.vrCompat().ForceMono && g_Config.bEnableStereo;
if (vrStereo) {
bool mirrored = vrMirroring[VR_MIRRORING_AXIS_Z] ^ (eye == 1);
bool mirrored = vrMirroring[VR_MIRRORING_AXIS_Z] ^ (matrix == VR_VIEW_MATRIX_RIGHT_EYE);
float dx = fabs(vrView[1].pose.position.x - vrView[0].pose.position.x);
float dy = fabs(vrView[1].pose.position.y - vrView[0].pose.position.y);
float dz = fabs(vrView[1].pose.position.z - vrView[0].pose.position.z);
Expand All @@ -940,6 +969,6 @@ void UpdateVRViewMatrices() {
M[11] += separation.z;
}

memcpy(vrViewMatrix[eye], M, sizeof(float) * 16);
memcpy(vrMatrix[matrix], M, sizeof(float) * 16);
}
}
1 change: 1 addition & 0 deletions Core/Compatibility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ void Compatibility::CheckVRSettings(IniFile &iniFile, const std::string &gameID)
CheckSetting(iniFile, gameID, "ForceMono", &vrCompat_.ForceMono);
CheckSetting(iniFile, gameID, "IdentityViewHack", &vrCompat_.IdentityViewHack);
CheckSetting(iniFile, gameID, "MirroringVariant", &vrCompat_.MirroringVariant);
CheckSetting(iniFile, gameID, "ProjectionHack", &vrCompat_.ProjectionHack);
CheckSetting(iniFile, gameID, "Skyplane", &vrCompat_.Skyplane);
CheckSetting(iniFile, gameID, "UnitsPerMeter", &vrCompat_.UnitsPerMeter);

Expand Down
1 change: 1 addition & 0 deletions Core/Compatibility.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ struct VRCompat {
bool ForceFlatScreen;
bool IdentityViewHack;
int MirroringVariant;
bool ProjectionHack;
bool Skyplane;
float UnitsPerMeter;
};
Expand Down
1 change: 1 addition & 0 deletions Core/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -958,6 +958,7 @@ static const ConfigSetting vrSettings[] = {
ConfigSetting("VRCameraPitch", &g_Config.iCameraPitch, 0, CfgFlag::PER_GAME),
ConfigSetting("VRCanvasDistance", &g_Config.fCanvasDistance, 12.0f, CfgFlag::DEFAULT),
ConfigSetting("VRCanvas3DDistance", &g_Config.fCanvas3DDistance, 3.0f, CfgFlag::DEFAULT),
ConfigSetting("VRFieldOfView", &g_Config.fFieldOfViewPercentage, 100.0f, CfgFlag::PER_GAME),
ConfigSetting("VRHeadUpDisplayScale", &g_Config.fHeadUpDisplayScale, 0.3f, CfgFlag::PER_GAME),
ConfigSetting("VRMotionLength", &g_Config.fMotionLength, 0.5f, CfgFlag::DEFAULT),
ConfigSetting("VRHeadRotationScale", &g_Config.fHeadRotationScale, 5.0f, CfgFlag::PER_GAME),
Expand Down
1 change: 1 addition & 0 deletions Core/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,7 @@ struct Config {
float fCameraSide;
float fCanvasDistance;
float fCanvas3DDistance;
float fFieldOfViewPercentage;
float fHeadUpDisplayScale;
float fMotionLength;
float fHeadRotationScale;
Expand Down
1 change: 1 addition & 0 deletions UI/GameSettingsScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1267,6 +1267,7 @@ void GameSettingsScreen::CreateVRSettings(UI::ViewGroup *vrSettings) {
vrSettings->Add(new ItemHeader(vr->T("VR camera")));
vrSettings->Add(new PopupSliderChoiceFloat(&g_Config.fCanvasDistance, 1.0f, 15.0f, 12.0f, vr->T("Distance to 2D menus and scenes"), 1.0f, screenManager(), ""));
vrSettings->Add(new PopupSliderChoiceFloat(&g_Config.fCanvas3DDistance, 1.0f, 15.0f, 3.0f, vr->T("Distance to 3D scenes when VR disabled"), 1.0f, screenManager(), ""));
vrSettings->Add(new PopupSliderChoiceFloat(&g_Config.fFieldOfViewPercentage, 100.0f, 200.0f, 100.0f, vr->T("Field of view scale"), 10.0f, screenManager(), vr->T("% of native FoV")));
vrSettings->Add(new CheckBox(&g_Config.bRescaleHUD, vr->T("Heads-up display detection")));
PopupSliderChoiceFloat* vrHudScale = vrSettings->Add(new PopupSliderChoiceFloat(&g_Config.fHeadUpDisplayScale, 0.0f, 1.5f, 0.3f, vr->T("Heads-up display scale"), 0.1f, screenManager(), ""));
vrHudScale->SetEnabledPtr(&g_Config.bRescaleHUD);
Expand Down
11 changes: 11 additions & 0 deletions assets/compatvr.ini
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,17 @@ ULES00035 = 3
ULUS10014 = 3


[ProjectionHack]
# Forces ignoring of projection matrix pivot point.

# Gran Turismo: The Real Driving Simulator
NPJG00027 = true
UCAS40265 = true
UCES01245 = true
UCJS10100 = true
UCUS98632 = true


[Skyplane]
# Workaround to remove the background skyplane and add clearing framebuffer with a fog color.

Expand Down
2 changes: 2 additions & 0 deletions assets/lang/ar_AE.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1403,11 +1403,13 @@ Download = ‎تحميل
New version of PPSSPP available = ‎تتوفر نسخة جديدة من البرنامج
[VR]
% of native FoV = % of native FoV
6DoF movement = 6DoF movement
Camera type = وضع الكاميرا
Distance to 2D menus and scenes = Distance to 2D menus and scenes
Distance to 3D scenes when VR disabled = Distance to 3D scenes when VR disabled
Experts only = Experts only
Field of view scale = Field of view scale
Force 72Hz update = Force 72Hz update
Game camera rotation step per frame = Game camera rotation step per frame
Game camera uses rotation smoothing = Game camera uses rotation smoothing
Expand Down
2 changes: 2 additions & 0 deletions assets/lang/az_AZ.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1395,11 +1395,13 @@ Download = Download
New version of PPSSPP available = New version of PPSSPP available
[VR]
% of native FoV = % of native FoV
6DoF movement = 6DoF movement
Camera type = Camera type
Distance to 2D menus and scenes = Distance to 2D menus and scenes
Distance to 3D scenes when VR disabled = Distance to 3D scenes when VR disabled
Experts only = Experts only
Field of view scale = Field of view scale
Force 72Hz update = Force 72Hz update
Game camera rotation step per frame = Game camera rotation step per frame
Game camera uses rotation smoothing = Game camera uses rotation smoothing
Expand Down
2 changes: 2 additions & 0 deletions assets/lang/bg_BG.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1395,11 +1395,13 @@ Download = Свали
New version of PPSSPP available = Налична е нова версия на PPSSPP
[VR]
% of native FoV = % of native FoV
6DoF movement = 6DoF movement
Camera type = Camera type
Distance to 2D menus and scenes = Distance to 2D menus and scenes
Distance to 3D scenes when VR disabled = Distance to 3D scenes when VR disabled
Experts only = Experts only
Field of view scale = Field of view scale
Force 72Hz update = Force 72Hz update
Game camera rotation step per frame = Game camera rotation step per frame
Game camera uses rotation smoothing = Game camera uses rotation smoothing
Expand Down
2 changes: 2 additions & 0 deletions assets/lang/ca_ES.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1395,11 +1395,13 @@ Download = Descarregar
New version of PPSSPP available = Nova versió de PPSSPP disponible

[VR]
% of native FoV = % of native FoV
6DoF movement = 6DoF movement
Camera type = Camera type
Distance to 2D menus and scenes = Distance to 2D menus and scenes
Distance to 3D scenes when VR disabled = Distance to 3D scenes when VR disabled
Experts only = Experts only
Field of view scale = Field of view scale
Force 72Hz update = Force 72Hz update
Game camera rotation step per frame = Game camera rotation step per frame
Game camera uses rotation smoothing = Game camera uses rotation smoothing
Expand Down
2 changes: 2 additions & 0 deletions assets/lang/cz_CZ.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1395,11 +1395,13 @@ Download = Stáhnout
New version of PPSSPP available = Je dostupná nová verze PPSSPP
[VR]
% of native FoV = % výchozího FoV
6DoF movement = 6DoF movement
Camera type = Camera type
Distance to 2D menus and scenes = Distance to 2D menus and scenes
Distance to 3D scenes when VR disabled = Distance to 3D scenes when VR disabled
Experts only = Experts only
Field of view scale = Poměr zorného pole
Force 72Hz update = Force 72Hz update
Game camera rotation step per frame = Game camera rotation step per frame
Game camera uses rotation smoothing = Game camera uses rotation smoothing
Expand Down
2 changes: 2 additions & 0 deletions assets/lang/da_DK.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1395,11 +1395,13 @@ Download = Download
New version of PPSSPP available = Ny version af PPSSPP tilgængelig

[VR]
% of native FoV = % of native FoV
6DoF movement = 6DoF movement
Camera type = Camera type
Distance to 2D menus and scenes = Distance to 2D menus and scenes
Distance to 3D scenes when VR disabled = Distance to 3D scenes when VR disabled
Experts only = Experts only
Field of view scale = Field of view scale
Force 72Hz update = Force 72Hz update
Game camera rotation step per frame = Game camera rotation step per frame
Game camera uses rotation smoothing = Game camera uses rotation smoothing
Expand Down
2 changes: 2 additions & 0 deletions assets/lang/de_DE.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1395,11 +1395,13 @@ Download = Herunterladen
New version of PPSSPP available = Neue PPSSPP Version verfügbar
[VR]
% of native FoV = % of native FoV
6DoF movement = 6DoF movement
Camera type = Kameratyp
Distance to 2D menus and scenes = Distance to 2D menus and scenes
Distance to 3D scenes when VR disabled = Distance to 3D scenes when VR disabled
Experts only = Experts only
Field of view scale = Field of view scale
Force 72Hz update = Force 72Hz update
Game camera rotation step per frame = Game camera rotation step per frame
Game camera uses rotation smoothing = Game camera uses rotation smoothing
Expand Down
2 changes: 2 additions & 0 deletions assets/lang/dr_ID.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1395,11 +1395,13 @@ Download = Download
New version of PPSSPP available = New version of PPSSPP available
[VR]
% of native FoV = % of native FoV
6DoF movement = 6DoF movement
Camera type = Camera type
Distance to 2D menus and scenes = Distance to 2D menus and scenes
Distance to 3D scenes when VR disabled = Distance to 3D scenes when VR disabled
Experts only = Experts only
Field of view scale = Field of view scale
Force 72Hz update = Force 72Hz update
Game camera rotation step per frame = Game camera rotation step per frame
Game camera uses rotation smoothing = Game camera uses rotation smoothing
Expand Down
2 changes: 2 additions & 0 deletions assets/lang/en_US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1420,12 +1420,14 @@ Progress: %1% = Progress: %1%
Screen representation = Screen representation
[VR]
% of native FoV = % of native FoV
6DoF movement = 6DoF movement
Distance to 2D menus and scenes = Distance to 2D menus and scenes
Distance to 3D scenes when VR disabled = Distance to 3D scenes when VR disabled
Experts only = Experts only
Game camera rotation step per frame = Game camera rotation step per frame
Game camera uses rotation smoothing = Game camera uses rotation smoothing
Field of view scale = Field of view scale
Force 72Hz update = Force 72Hz update
Heads-up display scale = Heads-up display scale
Heads-up display detection = Heads-up display detection
Expand Down
2 changes: 2 additions & 0 deletions assets/lang/es_ES.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1397,11 +1397,13 @@ Download = Descargar
New version of PPSSPP available = Nueva versión de PPSSPP disponible
[VR]
% of native FoV = % de campo de visión nativo
6DoF movement = Movimiento 6DoF
Camera type = Camera type
Distance to 2D menus and scenes = Distancia de los menús y escenas 2D
Distance to 3D scenes when VR disabled = Distance to 3D scenes when VR disabled
Experts only = Experts only
Field of view scale = Escala de campo de visión
Force 72Hz update = Forzar actualizar a 72Hz
Game camera rotation step per frame = Game camera rotation step per frame
Game camera uses rotation smoothing = Game camera uses rotation smoothing
Expand Down
2 changes: 2 additions & 0 deletions assets/lang/es_LA.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1397,11 +1397,13 @@ Download = Descargar
New version of PPSSPP available = Nueva versión de PPSSPP disponible
[VR]
% of native FoV = % of native FoV
6DoF movement = 6DoF movement
Camera type = Camera type
Distance to 2D menus and scenes = Distance to 2D menus and scenes
Distance to 3D scenes when VR disabled = Distance to 3D scenes when VR disabled
Experts only = Experts only
Field of view scale = Field of view scale
Force 72Hz update = Force 72Hz update
Game camera rotation step per frame = Game camera rotation step per frame
Game camera uses rotation smoothing = Game camera uses rotation smoothing
Expand Down
2 changes: 2 additions & 0 deletions assets/lang/fa_IR.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1395,11 +1395,13 @@ Download = دانلود
New version of PPSSPP available = ورژن جدیدی از ppsspp موجود است
[VR]
% of native FoV = % of native FoV
6DoF movement = 6DoF movement
Camera type = Camera type
Distance to 2D menus and scenes = Distance to 2D menus and scenes
Distance to 3D scenes when VR disabled = Distance to 3D scenes when VR disabled
Experts only = Experts only
Field of view scale = Field of view scale
Force 72Hz update = Force 72Hz update
Game camera rotation step per frame = Game camera rotation step per frame
Game camera uses rotation smoothing = Game camera uses rotation smoothing
Expand Down
2 changes: 2 additions & 0 deletions assets/lang/fi_FI.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1397,11 +1397,13 @@ Download = Lataa
New version of PPSSPP available = Uusi PPSSPP-versio saatavilla
[VR]
% of native FoV = % of native FoV
6DoF movement = 6DoF-liike (kuusi vapausastetta)
Camera type = Kameratyyppi
Distance to 2D menus and scenes = Etäisyys 2D-valikkoihin ja kohtauksiin
Distance to 3D scenes when VR disabled = Etäisyys 3D-kohtauksiin, kun VR on poistettu käytöstä
Experts only = Vain asiantuntijoille
Field of view scale = Field of view scale
Force 72Hz update = Pakota 72Hz päivitys
Game camera rotation step per frame = Pelikameran kiertovaihe per kuva
Game camera uses rotation smoothing = Pelikamera käyttää kiertotason tasoitusta
Expand Down
2 changes: 2 additions & 0 deletions assets/lang/fr_FR.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1386,11 +1386,13 @@ Download = Télécharger
New version of PPSSPP available = Nouvelle version de PPSSPP disponible
[VR]
% of native FoV = % of native FoV
6DoF movement = 6DoF movement
Camera type = Camera type
Distance to 2D menus and scenes = Distance to 2D menus and scenes
Distance to 3D scenes when VR disabled = Distance to 3D scenes when VR disabled
Experts only = Experts only
Field of view scale = Field of view scale
Force 72Hz update = Force 72Hz update
Game camera rotation step per frame = Game camera rotation step per frame
Game camera uses rotation smoothing = Game camera uses rotation smoothing
Expand Down
2 changes: 2 additions & 0 deletions assets/lang/gl_ES.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1395,11 +1395,13 @@ Download = Descargar
New version of PPSSPP available = Nova versión de PPSSPP dispoñible
[VR]
% of native FoV = % of native FoV
6DoF movement = 6DoF movement
Camera type = Camera type
Distance to 2D menus and scenes = Distance to 2D menus and scenes
Distance to 3D scenes when VR disabled = Distance to 3D scenes when VR disabled
Experts only = Experts only
Field of view scale = Field of view scale
Force 72Hz update = Force 72Hz update
Game camera rotation step per frame = Game camera rotation step per frame
Game camera uses rotation smoothing = Game camera uses rotation smoothing
Expand Down

0 comments on commit ad541f2

Please sign in to comment.