openvr icon indicating copy to clipboard operation
openvr copied to clipboard

Controller tracking is not as responsive as the default empty SteamVR environment

Open UltraEngine opened this issue 1 year ago • 3 comments

The tracking on my headset and controllers in my application is pretty good but not perfect. When I enable the SteamVR dashboard, the controller model that is visible in that interface does look perfectly smooth, and I would like my application to behave the same.

I'm following the examples and calling WaitGetPoses() before sending data and drawing:

vr::VRCompositor()->WaitGetPoses(m_rTrackedDevicePose.data(), vr::k_unMaxTrackedDeviceCount, NULL, 0);
		
for (int nDevice = 0; nDevice < vr::k_unMaxTrackedDeviceCount; ++nDevice)
{
	if (not m_rTrackedDevicePose[nDevice].bPoseIsValid) continue;
	switch (system->GetTrackedDeviceClass(nDevice))
	{
		case vr::TrackedDeviceClass_HMD:	

My CPU and GPU timing look great. Untitled

I found the GetDeviceToAbsoluteTrackingPose command, and used the timing code from the documentation, but the results look like the headset is overshooting the target orientation, and I am not sure if I am using this correctly:

vr::VRCompositor()->WaitGetPoses(m_rTrackedDevicePose.data(), vr::k_unMaxTrackedDeviceCount, NULL, 0);
		
// for somebody asking for the default figure out the time from now to photons.
float fSecondsSinceLastVsync;
system->GetTimeSinceLastVsync(&fSecondsSinceLastVsync, NULL);
float fDisplayFrequency = system->GetFloatTrackedDeviceProperty(vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_DisplayFrequency_Float);
float fFrameDuration = 1.f / fDisplayFrequency;
float fVsyncToPhotons = system->GetFloatTrackedDeviceProperty(vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_SecondsFromVsyncToPhotons_Float);
float fPredictedSecondsFromNow = fFrameDuration - fSecondsSinceLastVsync + fVsyncToPhotons;

system->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseStanding, fPredictedSecondsFromNow, m_rTrackedDevicePose.data(), m_rTrackedDevicePose.size());

for (int nDevice = 0; nDevice < vr::k_unMaxTrackedDeviceCount; ++nDevice)
{
	if (not m_rTrackedDevicePose[nDevice].bPoseIsValid) continue;

Am I doing something wrong?

UltraEngine avatar Nov 21 '23 02:11 UltraEngine

Pausing the debugger, I am seeing the following values in that time calculation:

fsecondssincelastvsync: 0.00550469989
frameDuration: 0.011
fsyntophotonsration: 0.011
fPredictedSecondsFrame: 0.0167175233

These values all seem plausible. However, even if I set fVsyncToPhotons to zero, with the above code, the tracking results are awful and lurching around.

In fact, even if I use 0 for the fPredictedSecondsToPhotonsFromNow argument, the orientation still lurches around drunkenly, even though the docs say the result should be the orientation at the exact time of the call. Clearly something is wrong here.

system->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseStanding, 0.0f, m_rTrackedDevicePose.data(), m_rTrackedDevicePose.size());

UltraEngine avatar Nov 21 '23 03:11 UltraEngine

You should uses the poses returned by WaitGetPoses for rendering controllers as well (instead of calling GetDeviceToAbsoluteTrackingPose yourself).

aleiby avatar Nov 21 '23 07:11 aleiby

You should uses the poses returned by WaitGetPoses for rendering controllers as well (instead of calling GetDeviceToAbsoluteTrackingPose yourself).

I don't understand this statement. Can you explain? We are not supposed to call GetDeviceToAbsoluteTrackingPose? What?

UltraEngine avatar Nov 21 '23 15:11 UltraEngine