Description:
When a user launches a game with the headset already worn, the current steamvr plugin code will never set the WornState to EHMDWornState::Worn.
Details:
The problem is the engine is only using the polling method:
while (VRSystem->PollNextEvent(&VREvent, sizeof(VREvent)))
And checking for the interaction started event:
case vr::VREvent_TrackedDeviceUserInteractionStarted:
// if the event was sent by the HMD
if (VREvent.trackedDeviceIndex == vr::k_unTrackedDeviceIndex_Hmd)
{
// Save the position we are currently at and put us in the state where we could move to a worn state
bShouldCheckHMDPosition = true;
HMDStartLocation = Position;
}
break;
However, this isn’t correct, because if the user begins the game already wearing the headset, VREvent_TrackedDeviceUserInteractionStarted will never fire. This also can happen if they begin the game in certain idle states.
From the OpenVR documentation:
/** Level of Hmd activity */
// UserInteraction_Timeout means the device is in the process of timing out.
// InUse = ( k_EDeviceActivityLevel_UserInteraction || k_EDeviceActivityLevel_UserInteraction_Timeout )
// VREvent_TrackedDeviceUserInteractionStarted fires when the devices transitions from Standby -> UserInteraction or Idle -> UserInteraction.
// VREvent_TrackedDeviceUserInteractionEnded fires when the devices transitions from UserInteraction_Timeout -> Idle
The engine should do an initial call to:
/** Returns the level of activity on the device. */
virtual EDeviceActivityLevel GetTrackedDeviceActivityLevel( vr::TrackedDeviceIndex_t unDeviceId ) = 0;
to determine if the HMD is worn, and then set the worn state appropriately. After an initial call to that it should be safe to stick to the event polling method for future transitions.