Merge pull request #17098 from lvonasek/feature_openxr_pitch_offset

OpenXR - Enable user to switch between topdown and fps camera
This commit is contained in:
Henrik Rydgård 2023-03-12 16:12:46 +01:00 committed by GitHub
commit 3feaa78c1c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 14 deletions

View file

@ -366,14 +366,14 @@ void UpdateVRInput(bool haptics, float dp_xscale, float dp_yscale) {
for (auto& axis : device.second) {
switch(axis.first) {
case JOYSTICK_AXIS_X:
if (axis.second < -0.75f) g_Config.fCameraSide -= 0.05f;
if (axis.second > 0.75f) g_Config.fCameraSide += 0.05f;
g_Config.fCameraSide = clampFloat(g_Config.fCameraSide, -50.0f, 50.0f);
if (axis.second < -0.75f) g_Config.fCameraSide -= 0.1f;
if (axis.second > 0.75f) g_Config.fCameraSide += 0.1f;
g_Config.fCameraSide = clampFloat(g_Config.fCameraSide, -150.0f, 150.0f);
break;
case JOYSTICK_AXIS_Y:
if (axis.second > 0.75f) g_Config.fCameraHeight -= 0.05f;
if (axis.second < -0.75f) g_Config.fCameraHeight += 0.05f;
g_Config.fCameraHeight = clampFloat(g_Config.fCameraHeight, -50.0f, 50.0f);
if (axis.second > 0.75f) g_Config.fCameraHeight -= 0.1f;
if (axis.second < -0.75f) g_Config.fCameraHeight += 0.1f;
g_Config.fCameraHeight = clampFloat(g_Config.fCameraHeight, -150.0f, 150.0f);
break;
case JOYSTICK_AXIS_Z:
if (axis.second < -0.75f) g_Config.fHeadUpDisplayScale -= 0.01f;
@ -383,7 +383,7 @@ void UpdateVRInput(bool haptics, float dp_xscale, float dp_yscale) {
case JOYSTICK_AXIS_RZ:
if (axis.second > 0.75f) g_Config.fCameraDistance -= 0.1f;
if (axis.second < -0.75f) g_Config.fCameraDistance += 0.1f;
g_Config.fCameraDistance = clampFloat(g_Config.fCameraDistance, -50.0f, 50.0f);
g_Config.fCameraDistance = clampFloat(g_Config.fCameraDistance, -150.0f, 150.0f);
break;
}
}
@ -665,6 +665,21 @@ bool StartVRRender() {
invView = XrPosef_Inverse(invView);
}
// apply camera pitch offset
XrVector3f positionOffset = {g_Config.fCameraSide, g_Config.fCameraHeight, g_Config.fCameraDistance};
if (!flatScreen) {
float pitchOffset = 0;
if (g_Config.iCameraPitch == 1) {
pitchOffset = 90;
positionOffset = {positionOffset.x, positionOffset.z, -positionOffset.y};
} else if (g_Config.iCameraPitch == 2) {
pitchOffset = -90;
positionOffset = {positionOffset.x, -positionOffset.z, positionOffset.y};
}
XrQuaternionf rotationOffset = XrQuaternionf_CreateFromVectorAngle({1, 0, 0}, ToRadians(pitchOffset));
invView.orientation = XrQuaternionf_Multiply(rotationOffset, invView.orientation);
}
// decompose rotation
XrVector3f rotation = XrQuaternionf_ToEulerAngles(invView.orientation);
float mPitch = mx * ToRadians(rotation.x);
@ -685,14 +700,14 @@ bool StartVRRender() {
memcpy(&M, M, sizeof(float) * 16);
// Apply 6Dof head movement
if (!flatScreen && g_Config.bEnable6DoF) {
if (!flatScreen && g_Config.bEnable6DoF && !g_Config.bHeadRotationEnabled && (g_Config.iCameraPitch == 0)) {
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;
}
// Camera adjust - distance
if (fabsf(g_Config.fCameraDistance) > 0.0f) {
XrVector3f forward = {0.0f, 0.0f, g_Config.fCameraDistance * scale};
if (fabsf(positionOffset.z) > 0.0f) {
XrVector3f forward = {0.0f, 0.0f, positionOffset.z * scale};
forward = XrQuaternionf_Rotate(invView.orientation, forward);
forward = XrVector3f_ScalarMultiply(forward, vrMirroring[VR_MIRRORING_AXIS_Z] ? -1.0f : 1.0f);
M[3] += forward.x;
@ -700,8 +715,8 @@ bool StartVRRender() {
M[11] += forward.z;
}
// Camera adjust - height
if (fabsf(g_Config.fCameraHeight) > 0.0f) {
XrVector3f up = {0.0f, -g_Config.fCameraHeight * scale, 0.0f};
if (fabsf(positionOffset.y) > 0.0f) {
XrVector3f up = {0.0f, -positionOffset.y * scale, 0.0f};
up = XrQuaternionf_Rotate(invView.orientation, up);
up = XrVector3f_ScalarMultiply(up, vrMirroring[VR_MIRRORING_AXIS_Y] ? -1.0f : 1.0f);
M[3] += up.x;
@ -709,8 +724,8 @@ bool StartVRRender() {
M[11] += up.z;
}
// Camera adjust - side
if (fabsf(g_Config.fCameraSide) > 0.0f) {
XrVector3f side = {-g_Config.fCameraSide * scale, 0.0f, 0.0f};
if (fabsf(positionOffset.x) > 0.0f) {
XrVector3f side = {-positionOffset.x * scale, 0.0f, 0.0f};
side = XrQuaternionf_Rotate(invView.orientation, side);
side = XrVector3f_ScalarMultiply(side, vrMirroring[VR_MIRRORING_AXIS_X] ? -1.0f : 1.0f);
M[3] += side.x;

View file

@ -1147,6 +1147,7 @@ static const ConfigSetting vrSettings[] = {
ConfigSetting("VRCameraDistance", &g_Config.fCameraDistance, 0.0f),
ConfigSetting("VRCameraHeight", &g_Config.fCameraHeight, 0.0f),
ConfigSetting("VRCameraSide", &g_Config.fCameraSide, 0.0f),
ConfigSetting("VRCameraPitch", &g_Config.iCameraPitch, 0),
ConfigSetting("VRCanvasDistance", &g_Config.fCanvasDistance, 12.0f),
ConfigSetting("VRFieldOfView", &g_Config.fFieldOfViewPercentage, 100.0f),
ConfigSetting("VRHeadUpDisplayScale", &g_Config.fHeadUpDisplayScale, 0.3f),

View file

@ -472,6 +472,7 @@ public:
float fHeadRotationScale;
bool bHeadRotationEnabled;
bool bHeadRotationSmoothing;
int iCameraPitch;
// Debugger
int iDisasmWindowX;

View file

@ -1151,6 +1151,8 @@ void GameSettingsScreen::CreateVRSettings(UI::ViewGroup *vrSettings) {
vrSettings->Add(new CheckBox(&g_Config.bEnableMotions, vr->T("Map controller movements to keys")));
PopupSliderChoiceFloat *vrMotions = vrSettings->Add(new PopupSliderChoiceFloat(&g_Config.fMotionLength, 0.3f, 1.0f, vr->T("Motion needed to generate action"), 0.1f, screenManager(), vr->T("m")));
vrMotions->SetEnabledPtr(&g_Config.bEnableMotions);
static const char *cameraPitchModes[] = { "Disabled", "Top view -> First person", "First person -> Top view" };
vrSettings->Add(new PopupMultiChoice(&g_Config.iCameraPitch, vr->T("Modify camera type"), cameraPitchModes, 0, 3, "", screenManager()));
}
UI::LinearLayout *GameSettingsScreen::AddTab(const char *tag, const std::string &title, bool isSearch) {