diff --git a/android/app/src/main/cpp/code/vr/vr_input.c b/android/app/src/main/cpp/code/vr/vr_input.c index aa008c52..d47d176c 100644 --- a/android/app/src/main/cpp/code/vr/vr_input.c +++ b/android/app/src/main/cpp/code/vr/vr_input.c @@ -40,6 +40,7 @@ XrAction vibrateRightFeedback; XrActionSet runningActionSet; XrSpace leftControllerAimSpace = XR_NULL_HANDLE; XrSpace rightControllerAimSpace = XR_NULL_HANDLE; +qboolean actionsAttached = qfalse; qboolean inputInitialized = qfalse; qboolean useSimpleProfile = qfalse; @@ -1364,12 +1365,15 @@ void IN_VRSyncActions( void ) engine_t* engine = VR_GetEngine(); // Attach to session - XrSessionActionSetsAttachInfo attachInfo = {}; - attachInfo.type = XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO; - attachInfo.next = NULL; - attachInfo.countActionSets = 1; - attachInfo.actionSets = &runningActionSet; - OXR(xrAttachSessionActionSets(engine->appState.Session, &attachInfo)); + if (!actionsAttached) { + XrSessionActionSetsAttachInfo attachInfo = {}; + attachInfo.type = XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO; + attachInfo.next = NULL; + attachInfo.countActionSets = 1; + attachInfo.actionSets = &runningActionSet; + OXR(xrAttachSessionActionSets(engine->appState.Session, &attachInfo)); + actionsAttached = qtrue; + } // sync action data XrActiveActionSet activeActionSet = {}; @@ -1390,7 +1394,7 @@ void IN_VRSyncActions( void ) getInfo.subactionPath = XR_NULL_PATH; } -void IN_VRUpdateControllers( float predictedDisplayTime ) +void IN_VRUpdateControllers( XrPosef xfStageFromHead, float predictedDisplayTime ) { engine_t* engine = VR_GetEngine(); @@ -1400,21 +1404,12 @@ void IN_VRUpdateControllers( float predictedDisplayTime ) XrSpace controllerSpace[] = {leftControllerAimSpace, rightControllerAimSpace}; for (int i = 0; i < 2; i++) { if (ActionPoseIsActive(controller[i], subactionPath[i])) { - XrSpaceVelocity vel = {}; - vel.type = XR_TYPE_SPACE_VELOCITY; XrSpaceLocation loc = {}; loc.type = XR_TYPE_SPACE_LOCATION; - loc.next = &vel; - OXR(xrLocateSpace(controllerSpace[i], engine->appState.CurrentSpace, predictedDisplayTime, &loc)); + OXR(xrLocateSpace(controllerSpace[i], engine->appState.HeadSpace, predictedDisplayTime, &loc)); engine->appState.TrackedController[i].Active = (loc.locationFlags & XR_SPACE_LOCATION_POSITION_VALID_BIT) != 0; - engine->appState.TrackedController[i].Pose = 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; - } + engine->appState.TrackedController[i].Pose = XrPosef_Multiply(xfStageFromHead, loc.pose); } else { ovrTrackedController_Clear(&engine->appState.TrackedController[i]); } @@ -1427,16 +1422,10 @@ void IN_VRUpdateControllers( float predictedDisplayTime ) 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 // 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 XrVector3f positionHmd = xfStageFromHead.position; 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]; vr.clientview_yaw_delta = vr.clientview_yaw_last - clientview_yaw; vr.clientview_yaw_last = clientview_yaw; - - return xfStageFromHead; } //#endif diff --git a/android/app/src/main/cpp/code/vr/vr_input.h b/android/app/src/main/cpp/code/vr/vr_input.h index 358cb5fb..3da499a5 100644 --- a/android/app/src/main/cpp/code/vr/vr_input.h +++ b/android/app/src/main/cpp/code/vr/vr_input.h @@ -9,8 +9,8 @@ void IN_VRInputFrame( void ); void IN_VRInit( void ); void IN_VRSyncActions( void ); -XrPosef IN_VRUpdateHMD( float predictedDisplayTime ); -void IN_VRUpdateControllers( float predictedDisplayTime ); +void IN_VRUpdateHMD( XrPosef xfStageFromHead ); +void IN_VRUpdateControllers( XrPosef xfStageFromHead, float predictedDisplayTime ); void QuatToYawPitchRoll(XrQuaternionf q, vec3_t rotation, vec3_t out); diff --git a/android/app/src/main/cpp/code/vr/vr_renderer.c b/android/app/src/main/cpp/code/vr/vr_renderer.c index 2e4885ab..0b0a58a9 100644 --- a/android/app/src/main/cpp/code/vr/vr_renderer.c +++ b/android/app/src/main/cpp/code/vr/vr_renderer.c @@ -384,16 +384,11 @@ void VR_DrawFrame( engine_t* engine ) { beginFrameDesc.next = NULL; OXR(xrBeginFrame(engine->appState.Session, &beginFrameDesc)); - // Update HMD and controllers - XrPosef xfStageFromHead = IN_VRUpdateHMD( frameState.predictedDisplayTime ); - IN_VRSyncActions(); - IN_VRUpdateControllers( frameState.predictedDisplayTime ); - XrViewLocateInfo projectionInfo = {}; projectionInfo.type = XR_TYPE_VIEW_LOCATE_INFO; projectionInfo.viewConfigurationType = engine->appState.ViewportConfig.viewConfigurationType; projectionInfo.displayTime = frameState.predictedDisplayTime; - projectionInfo.space = engine->appState.HeadSpace; + projectionInfo.space = engine->appState.CurrentSpace; XrViewState viewState = {XR_TYPE_VIEW_STATE, NULL}; @@ -410,11 +405,9 @@ void VR_DrawFrame( engine_t* engine ) { // XrFovf fov = {}; - XrPosef viewTransform[2]; + XrPosef invViewTransform[2]; for (int eye = 0; eye < ovrMaxNumEyes; eye++) { - XrPosef xfHeadFromEye = projections[eye].pose; - XrPosef xfStageFromEye = XrPosef_Multiply(xfStageFromHead, xfHeadFromEye); - viewTransform[eye] = XrPosef_Inverse(xfStageFromEye); + invViewTransform[eye] = projections[eye].pose; fov.angleLeft += projections[eye].fov.angleLeft / 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_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 float hudScale = M_PI * 15.0f / 180.0f; const ovrMatrix4f monoVRMatrix = ovrMatrix4f_CreateProjectionFov( @@ -467,7 +465,7 @@ void VR_DrawFrame( engine_t* engine ) { memset(&projection_layer_elements[eye], 0, sizeof(XrCompositionLayerProjectionView)); 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; memset(&projection_layer_elements[eye].subImage, 0, sizeof(XrSwapchainSubImage)); @@ -507,9 +505,9 @@ void VR_DrawFrame( engine_t* engine ) { cylinder_layer.subImage.imageArrayIndex = 0; const XrVector3f axis = {0.0f, 1.0f, 0.0f}; XrVector3f pos = { - xfStageFromHead.position.x - sin(radians(vr.menuYaw)) * 4.0f, + invViewTransform[0].position.x - sin(radians(vr.menuYaw)) * 4.0f, -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.position = pos;