ValveSoftware / unity-xr-plugin

OpenVR plugin for Unity's XR API

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

XR Plugin reports wrong eye positions

Shii2 opened this issue · comments

commented

Left and Right eye position Y an Z coordinates always equals to Center eye Y and Z coordinates.
Here is a video demonstrating the problem: https://www.youtube.com/watch?v=9Bp0c7_XvuY
Reproduced problem in both Unity 2019.4.22f1 and Unity 2020.3.0f1, using SteamVR 1.16.10, OpenVR Unity XR plugin v1.1.4 and Oculus Rift CV1 headset.
This is the only bug preventing us from migrating our project from Legacy VR and Unity 2019.4.22f1 to XR Plugin and Unity 2020.3
Here is the code that used in above video to report eye positions:

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.XR;

public class EyePosTest : MonoBehaviour
{
	public Text leftEyePosValue;
	public Text rightEyePosValue;
	public Text centerEyePosValue;
	public Text headPosValue;

	void Update()
	{
		Vector3 leftEyePosition;
		Vector3 rightEyePosition;
		Vector3 centerEyePosition;
		Vector3 headPosition;
		TryGetEyeFeature(out leftEyePosition, XRNode.LeftEye);
		TryGetEyeFeature(out rightEyePosition, XRNode.RightEye);
		TryGetEyeFeature(out centerEyePosition, XRNode.CenterEye);
		TryGetEyeFeature(out headPosition, XRNode.Head);
		leftEyePosValue.text = leftEyePosition.ToString("F4");
		rightEyePosValue.text = rightEyePosition.ToString("F4");
		centerEyePosValue.text = centerEyePosition.ToString("F4");
		headPosValue.text = headPosition.ToString("F4");
	}

	private bool TryGetEyeFeature(out Vector3 position, XRNode eye)
	{
		InputFeatureUsage<Vector3> inputFeatureUsage = CommonUsages.devicePosition;
		if (eye == XRNode.LeftEye)
			inputFeatureUsage = CommonUsages.leftEyePosition;
		else if (eye == XRNode.RightEye)
			inputFeatureUsage = CommonUsages.rightEyePosition;
		else if (eye == XRNode.CenterEye)
			inputFeatureUsage = CommonUsages.centerEyePosition;
		else if (eye == XRNode.Head)
			inputFeatureUsage = CommonUsages.devicePosition;

		InputDevice device = InputDevices.GetDeviceAtXRNode(XRNode.Head);
		if (device.isValid)
		{
			if (device.TryGetFeatureValue(inputFeatureUsage, out position))
				return true;
		}
		// This is the fail case
		position = Vector3.zero;
		return false;
	}
}

image

Another visualisation of the bug, with headset looking straight on, and looking to the right. The left eye (green) and right eye (red) are also flipped over.
The do not rotate around the centre point as would be expected.

commented

Analyzed unity-xr-plugin source code and found a fix!
Issue was found in file

xrTrackingTransformRef *= reinterpret_cast< XRMatrix4x4 & >( *postTransform );
at line 477 and this happens because wrong matrix multiplication order is used.
To fix the issue replace this line with:
xrTrackingTransformRef = reinterpret_cast< XRMatrix4x4 & >( *postTransform ) * xrTrackingTransformRef;