@@ -644,6 +644,9 @@ struct DeviceDelegateOculusVR::State {
644644 ovrInputTrackedRemoteCapabilities capabilities = {};
645645 vrb::Matrix transform = vrb::Matrix::Identity();
646646 ovrInputStateTrackedRemote inputState = {};
647+ uint64_t inputFrameID = 0 ;
648+ float remainingVibrateTime = 0 .0f ;
649+ double lastHapticUpdateTimeStamp = 0 .0f ;
647650
648651 bool Is6DOF () const {
649652 return (capabilities.ControllerCapabilities & ovrControllerCaps_HasPositionTracking) &&
@@ -692,7 +695,6 @@ struct DeviceDelegateOculusVR::State {
692695 device::CPULevel minCPULevel = device::CPULevel::Normal;
693696 device::DeviceType deviceType = device::UnknownType;
694697
695-
696698 void UpdatePerspective () {
697699 float fovX = vrapi_GetSystemPropertyFloat (&java, VRAPI_SYS_PROP_SUGGESTED_EYE_FOV_DEGREES_X);
698700 float fovY = vrapi_GetSystemPropertyFloat (&java, VRAPI_SYS_PROP_SUGGESTED_EYE_FOV_DEGREES_Y);
@@ -952,10 +954,13 @@ struct DeviceDelegateOculusVR::State {
952954 controller->CreateController (controllerState.index , int32_t (controllerState.hand ),
953955 controllerName, beamTransform);
954956 controller->SetButtonCount (controllerState.index , 6 );
957+ controller->SetHapticCount (controllerState.index , 1 );
955958 } else {
956959 // Oculus Go only has one kind of controller model.
957960 controller->CreateController (controllerState.index , 0 , " Oculus Go Controller" );
958961 controller->SetButtonCount (controllerState.index , 2 );
962+ // Oculus Go has no haptic feedback.
963+ controller->SetHapticCount (controllerState.index , 0 );
959964 }
960965 controllerState.created = true ;
961966 }
@@ -1037,7 +1042,6 @@ struct DeviceDelegateOculusVR::State {
10371042 const bool yTouched = (controllerState.inputState .Touches & ovrTouch_Y) != 0 ;
10381043 const bool menuPressed = (controllerState.inputState .Buttons & ovrButton_Enter) != 0 ;
10391044
1040-
10411045 controller->SetButtonState (controllerState.index , ControllerDelegate::BUTTON_X, 3 , xPressed, xTouched);
10421046 controller->SetButtonState (controllerState.index , ControllerDelegate::BUTTON_Y, 4 , yPressed, yTouched);
10431047
@@ -1062,7 +1066,8 @@ struct DeviceDelegateOculusVR::State {
10621066 VRB_WARN (" Undefined hand type in DeviceDelegateOculusVR." );
10631067 }
10641068
1065- const bool thumbRest = (controllerState.inputState .Touches & ovrTouch_ThumbUp) != 0 ;
1069+ // This is always false in Oculus Browser.
1070+ const bool thumbRest = false ;
10661071 controller->SetButtonState (controllerState.index , ControllerDelegate::BUTTON_OTHERS, 5 , thumbRest, thumbRest);
10671072 } else {
10681073 triggerPressed = (controllerState.inputState .Buttons & ovrButton_A) != 0 ;
@@ -1093,6 +1098,58 @@ struct DeviceDelegateOculusVR::State {
10931098 controller->SetButtonState (controllerState.index , ControllerDelegate::BUTTON_TOUCHPAD, 0 , trackpadPressed, trackpadTouched);
10941099
10951100 controller->SetAxes (controllerState.index , axes, kNumAxes );
1101+ if (controller->GetHapticCount (controllerState.index )) {
1102+ UpdateHaptics (controllerState);
1103+ }
1104+ }
1105+ }
1106+
1107+ void UpdateHaptics (ControllerState& controllerState) {
1108+ vrb::RenderContextPtr renderContext = context.lock ();
1109+ if (!renderContext) {
1110+ return ;
1111+ }
1112+ if (!controller || !ovr) {
1113+ return ;
1114+ }
1115+
1116+ uint64_t inputFrameID = 0 ;
1117+ float pulseDuration = 0 .0f , pulseIntensity = 0 .0f ;
1118+ controller->GetHapticFeedback (controllerState.index , inputFrameID, pulseDuration, pulseIntensity);
1119+ if (inputFrameID > 0 && pulseIntensity > 0 .0f && pulseDuration > 0 ) {
1120+ if (controllerState.inputFrameID != inputFrameID) {
1121+ // When there is a new input frame id from haptic vibration,
1122+ // that means we start a new session for a vibration.
1123+ controllerState.inputFrameID = inputFrameID;
1124+ controllerState.remainingVibrateTime = pulseDuration;
1125+ controllerState.lastHapticUpdateTimeStamp = renderContext->GetTimestamp ();
1126+ } else {
1127+ // We are still running the previous vibration.
1128+ // So, it needs to reduce the delta time from the last vibration.
1129+ const double timeStamp = renderContext->GetTimestamp ();
1130+ controllerState.remainingVibrateTime -= (timeStamp - controllerState.lastHapticUpdateTimeStamp );
1131+ controllerState.lastHapticUpdateTimeStamp = timeStamp;
1132+ }
1133+
1134+ if (controllerState.remainingVibrateTime > 0 .0f && renderMode == device::RenderMode::Immersive) {
1135+ if (vrapi_SetHapticVibrationSimple (ovr, controllerState.deviceId , pulseIntensity > 1 .0f ? 1 .0f : pulseIntensity)
1136+ == ovrError_InvalidOperation) {
1137+ VRB_ERROR (" vrapi_SetHapticVibrationBuffer failed." );
1138+ }
1139+ } else {
1140+ // The remaining time is zero or exiting the immersive mode, stop the vibration.
1141+ if (vrapi_SetHapticVibrationSimple (ovr, controllerState.deviceId , 0 .0f ) == ovrError_InvalidOperation) {
1142+ VRB_ERROR (" vrapi_SetHapticVibrationBuffer failed." );
1143+ }
1144+ controllerState.remainingVibrateTime = 0 .0f ;
1145+ }
1146+ } else if (controllerState.remainingVibrateTime > 0 .0f ) {
1147+ // While the haptic feedback is terminated from the client side,
1148+ // but it still have remaining time, we need to ask for stopping vibration.
1149+ if (vrapi_SetHapticVibrationSimple (ovr, controllerState.deviceId , 0 .0f ) == ovrError_InvalidOperation) {
1150+ VRB_ERROR (" vrapi_SetHapticVibrationBuffer failed." );
1151+ }
1152+ controllerState.remainingVibrateTime = 0 .0f ;
10961153 }
10971154 }
10981155
0 commit comments