Merge pull request #81 from lvonasek/hotfix_openxr

OpenXR jitter hotfix
This commit is contained in:
Simon 2022-05-14 12:19:37 +01:00 committed by GitHub
commit d90f86e035
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 42 deletions

View file

@ -40,6 +40,7 @@ XrAction vibrateRightFeedback;
XrActionSet runningActionSet; XrActionSet runningActionSet;
XrSpace leftControllerAimSpace = XR_NULL_HANDLE; XrSpace leftControllerAimSpace = XR_NULL_HANDLE;
XrSpace rightControllerAimSpace = XR_NULL_HANDLE; XrSpace rightControllerAimSpace = XR_NULL_HANDLE;
qboolean actionsAttached = qfalse;
qboolean inputInitialized = qfalse; qboolean inputInitialized = qfalse;
qboolean useSimpleProfile = qfalse; qboolean useSimpleProfile = qfalse;
@ -1364,12 +1365,15 @@ void IN_VRSyncActions( void )
engine_t* engine = VR_GetEngine(); engine_t* engine = VR_GetEngine();
// Attach to session // Attach to session
XrSessionActionSetsAttachInfo attachInfo = {}; if (!actionsAttached) {
attachInfo.type = XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO; XrSessionActionSetsAttachInfo attachInfo = {};
attachInfo.next = NULL; attachInfo.type = XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO;
attachInfo.countActionSets = 1; attachInfo.next = NULL;
attachInfo.actionSets = &runningActionSet; attachInfo.countActionSets = 1;
OXR(xrAttachSessionActionSets(engine->appState.Session, &attachInfo)); attachInfo.actionSets = &runningActionSet;
OXR(xrAttachSessionActionSets(engine->appState.Session, &attachInfo));
actionsAttached = qtrue;
}
// sync action data // sync action data
XrActiveActionSet activeActionSet = {}; XrActiveActionSet activeActionSet = {};
@ -1390,7 +1394,7 @@ void IN_VRSyncActions( void )
getInfo.subactionPath = XR_NULL_PATH; getInfo.subactionPath = XR_NULL_PATH;
} }
void IN_VRUpdateControllers( float predictedDisplayTime ) void IN_VRUpdateControllers( XrPosef xfStageFromHead, float predictedDisplayTime )
{ {
engine_t* engine = VR_GetEngine(); engine_t* engine = VR_GetEngine();
@ -1400,21 +1404,12 @@ void IN_VRUpdateControllers( float predictedDisplayTime )
XrSpace controllerSpace[] = {leftControllerAimSpace, rightControllerAimSpace}; XrSpace controllerSpace[] = {leftControllerAimSpace, rightControllerAimSpace};
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
if (ActionPoseIsActive(controller[i], subactionPath[i])) { if (ActionPoseIsActive(controller[i], subactionPath[i])) {
XrSpaceVelocity vel = {};
vel.type = XR_TYPE_SPACE_VELOCITY;
XrSpaceLocation loc = {}; XrSpaceLocation loc = {};
loc.type = XR_TYPE_SPACE_LOCATION; loc.type = XR_TYPE_SPACE_LOCATION;
loc.next = &vel; OXR(xrLocateSpace(controllerSpace[i], engine->appState.HeadSpace, predictedDisplayTime, &loc));
OXR(xrLocateSpace(controllerSpace[i], engine->appState.CurrentSpace, predictedDisplayTime, &loc));
engine->appState.TrackedController[i].Active = (loc.locationFlags & XR_SPACE_LOCATION_POSITION_VALID_BIT) != 0; engine->appState.TrackedController[i].Active = (loc.locationFlags & XR_SPACE_LOCATION_POSITION_VALID_BIT) != 0;
engine->appState.TrackedController[i].Pose = loc.pose; engine->appState.TrackedController[i].Pose = XrPosef_Multiply(xfStageFromHead, loc.pose);
// apply velocity
float dt = (in_vrEventTime - lastframetime) * 0.001f;
for (int j = 0; j < 3; j++) {
(&engine->appState.TrackedController[i].Pose.position.x)[j] += (&vel.linearVelocity.x)[j] * dt;
}
} else { } else {
ovrTrackedController_Clear(&engine->appState.TrackedController[i]); ovrTrackedController_Clear(&engine->appState.TrackedController[i]);
} }
@ -1427,16 +1422,10 @@ void IN_VRUpdateControllers( float predictedDisplayTime )
IN_VRController(qtrue, engine->appState.TrackedController[1].Pose); IN_VRController(qtrue, engine->appState.TrackedController[1].Pose);
} }
XrPosef IN_VRUpdateHMD( float predictedDisplayTime ) void IN_VRUpdateHMD( XrPosef xfStageFromHead )
{ {
engine_t* engine = VR_GetEngine();
// We extract Yaw, Pitch, Roll instead of directly using the orientation // We extract Yaw, Pitch, Roll instead of directly using the orientation
// to allow "additional" yaw manipulation with mouse/controller. // to allow "additional" yaw manipulation with mouse/controller.
XrSpaceLocation loc = {};
loc.type = XR_TYPE_SPACE_LOCATION;
OXR(xrLocateSpace(engine->appState.HeadSpace, engine->appState.CurrentSpace, predictedDisplayTime, &loc));
XrPosef xfStageFromHead = loc.pose;
const XrQuaternionf quatHmd = xfStageFromHead.orientation; const XrQuaternionf quatHmd = xfStageFromHead.orientation;
const XrVector3f positionHmd = xfStageFromHead.position; const XrVector3f positionHmd = xfStageFromHead.position;
vec3_t rotation = {0, 0, 0}; vec3_t rotation = {0, 0, 0};
@ -1459,8 +1448,6 @@ XrPosef IN_VRUpdateHMD( float predictedDisplayTime )
const float clientview_yaw = vr.clientviewangles[YAW] - vr.hmdorientation[YAW]; const float clientview_yaw = vr.clientviewangles[YAW] - vr.hmdorientation[YAW];
vr.clientview_yaw_delta = vr.clientview_yaw_last - clientview_yaw; vr.clientview_yaw_delta = vr.clientview_yaw_last - clientview_yaw;
vr.clientview_yaw_last = clientview_yaw; vr.clientview_yaw_last = clientview_yaw;
return xfStageFromHead;
} }
//#endif //#endif

View file

@ -9,8 +9,8 @@
void IN_VRInputFrame( void ); void IN_VRInputFrame( void );
void IN_VRInit( void ); void IN_VRInit( void );
void IN_VRSyncActions( void ); void IN_VRSyncActions( void );
XrPosef IN_VRUpdateHMD( float predictedDisplayTime ); void IN_VRUpdateHMD( XrPosef xfStageFromHead );
void IN_VRUpdateControllers( float predictedDisplayTime ); void IN_VRUpdateControllers( XrPosef xfStageFromHead, float predictedDisplayTime );
void QuatToYawPitchRoll(XrQuaternionf q, vec3_t rotation, vec3_t out); void QuatToYawPitchRoll(XrQuaternionf q, vec3_t rotation, vec3_t out);

View file

@ -384,16 +384,11 @@ void VR_DrawFrame( engine_t* engine ) {
beginFrameDesc.next = NULL; beginFrameDesc.next = NULL;
OXR(xrBeginFrame(engine->appState.Session, &beginFrameDesc)); OXR(xrBeginFrame(engine->appState.Session, &beginFrameDesc));
// Update HMD and controllers
XrPosef xfStageFromHead = IN_VRUpdateHMD( frameState.predictedDisplayTime );
IN_VRSyncActions();
IN_VRUpdateControllers( frameState.predictedDisplayTime );
XrViewLocateInfo projectionInfo = {}; XrViewLocateInfo projectionInfo = {};
projectionInfo.type = XR_TYPE_VIEW_LOCATE_INFO; projectionInfo.type = XR_TYPE_VIEW_LOCATE_INFO;
projectionInfo.viewConfigurationType = engine->appState.ViewportConfig.viewConfigurationType; projectionInfo.viewConfigurationType = engine->appState.ViewportConfig.viewConfigurationType;
projectionInfo.displayTime = frameState.predictedDisplayTime; projectionInfo.displayTime = frameState.predictedDisplayTime;
projectionInfo.space = engine->appState.HeadSpace; projectionInfo.space = engine->appState.CurrentSpace;
XrViewState viewState = {XR_TYPE_VIEW_STATE, NULL}; XrViewState viewState = {XR_TYPE_VIEW_STATE, NULL};
@ -410,11 +405,9 @@ void VR_DrawFrame( engine_t* engine ) {
// //
XrFovf fov = {}; XrFovf fov = {};
XrPosef viewTransform[2]; XrPosef invViewTransform[2];
for (int eye = 0; eye < ovrMaxNumEyes; eye++) { for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
XrPosef xfHeadFromEye = projections[eye].pose; invViewTransform[eye] = projections[eye].pose;
XrPosef xfStageFromEye = XrPosef_Multiply(xfStageFromHead, xfHeadFromEye);
viewTransform[eye] = XrPosef_Inverse(xfStageFromEye);
fov.angleLeft += projections[eye].fov.angleLeft / 2.0f; fov.angleLeft += projections[eye].fov.angleLeft / 2.0f;
fov.angleRight += projections[eye].fov.angleRight / 2.0f; fov.angleRight += projections[eye].fov.angleRight / 2.0f;
@ -424,6 +417,11 @@ void VR_DrawFrame( engine_t* engine ) {
vr.fov_x = (fabs(fov.angleLeft) + fabs(fov.angleRight)) * 180.0f / M_PI; vr.fov_x = (fabs(fov.angleLeft) + fabs(fov.angleRight)) * 180.0f / M_PI;
vr.fov_y = (fabs(fov.angleUp) + fabs(fov.angleDown)) * 180.0f / M_PI; vr.fov_y = (fabs(fov.angleUp) + fabs(fov.angleDown)) * 180.0f / M_PI;
// Update HMD and controllers
IN_VRUpdateHMD( invViewTransform[0] );
IN_VRUpdateControllers( invViewTransform[0], frameState.predictedDisplayTime );
IN_VRSyncActions();
//Projection used for drawing HUD models etc //Projection used for drawing HUD models etc
float hudScale = M_PI * 15.0f / 180.0f; float hudScale = M_PI * 15.0f / 180.0f;
const ovrMatrix4f monoVRMatrix = ovrMatrix4f_CreateProjectionFov( const ovrMatrix4f monoVRMatrix = ovrMatrix4f_CreateProjectionFov(
@ -467,7 +465,7 @@ void VR_DrawFrame( engine_t* engine ) {
memset(&projection_layer_elements[eye], 0, sizeof(XrCompositionLayerProjectionView)); memset(&projection_layer_elements[eye], 0, sizeof(XrCompositionLayerProjectionView));
projection_layer_elements[eye].type = XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW; projection_layer_elements[eye].type = XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW;
projection_layer_elements[eye].pose = XrPosef_Inverse(viewTransform[eye]); projection_layer_elements[eye].pose = invViewTransform[eye];
projection_layer_elements[eye].fov = fov; projection_layer_elements[eye].fov = fov;
memset(&projection_layer_elements[eye].subImage, 0, sizeof(XrSwapchainSubImage)); memset(&projection_layer_elements[eye].subImage, 0, sizeof(XrSwapchainSubImage));
@ -507,9 +505,9 @@ void VR_DrawFrame( engine_t* engine ) {
cylinder_layer.subImage.imageArrayIndex = 0; cylinder_layer.subImage.imageArrayIndex = 0;
const XrVector3f axis = {0.0f, 1.0f, 0.0f}; const XrVector3f axis = {0.0f, 1.0f, 0.0f};
XrVector3f pos = { XrVector3f pos = {
xfStageFromHead.position.x - sin(radians(vr.menuYaw)) * 4.0f, invViewTransform[0].position.x - sin(radians(vr.menuYaw)) * 4.0f,
-0.25f, -0.25f,
xfStageFromHead.position.z - cos(radians(vr.menuYaw)) * 4.0f invViewTransform[0].position.z - cos(radians(vr.menuYaw)) * 4.0f
}; };
cylinder_layer.pose.orientation = XrQuaternionf_CreateFromVectorAngle(axis, radians(vr.menuYaw)); cylinder_layer.pose.orientation = XrQuaternionf_CreateFromVectorAngle(axis, radians(vr.menuYaw));
cylinder_layer.pose.position = pos; cylinder_layer.pose.position = pos;