Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Rotation only tracking on Oculus Quest

Discussion in 'AR/VR (XR) Discussion' started by ViliusVal, Aug 21, 2020.

  1. ViliusVal

    ViliusVal

    Joined:
    Nov 7, 2019
    Posts:
    2
    Hi,

    I'm using the new XR Toolkit on 2019.4.8f. I've set up a stationary XR rig with the Tracked Pose Driver set to Rotation only mode. When I move around in the app my controllers get offset by the movement, making them float off in the distance. I assume this offset it applied within the XR Controller class.

    Is there a quick fix I could apply?

    Solution
    Inside the XRController.cs I've added a couple of lines of code
    0. Add dependency of
    Code (CSharp):
    1. using UnityEngine.SpatialTracking;
    1. Make property that will allow you to track the head of the user
    Code (CSharp):
    1.        
    2. private InputDevice m_HeadInputDevice;
    3. ....
    4. public InputDevice headInputDevice
    5.         {
    6.             get
    7.             {
    8.                 return m_HeadInputDevice.isValid ? m_HeadInputDevice : (m_HeadInputDevice = InputDevices.GetDeviceAtXRNode(XRNode.CenterEye));
    9.             }
    10.         }
    11.  
    2. Inside the Awake function find and initiate the tracking type
    Code (CSharp):
    1.  
    2. private TrackedPoseDriver.TrackingType m_trackingType;
    3. ....
    4. var trackedPoseDriver = FindObjectOfType<TrackedPoseDriver>();
    5. m_trackingType = trackedPoseDriver.trackingType;
    6.  
    3. Find this line of code
    Code (CSharp):
    1. if (inputDevice.TryGetFeatureValue(CommonUsages.devicePosition, out devicePosition))
    2.                     transform.localPosition = devicePosition;
    and replace it with
    Code (CSharp):
    1. if (inputDevice.TryGetFeatureValue(CommonUsages.devicePosition, out devicePosition))
    2.                 {
    3.                     if (m_trackingType == TrackedPoseDriver.TrackingType.RotationOnly)
    4.                     {
    5.                         if (headInputDevice.TryGetFeatureValue(CommonUsages.centerEyePosition, out centerEyePosition))
    6.                         {
    7.                             transform.localPosition = devicePosition - centerEyePosition;
    8.                         }
    9.                     }
    10.                     else
    11.                     {
    12.                         transform.localPosition = devicePosition;
    13.                     }
    14.                 }
    This will essentially offset the controller position using the head position.
    Update:
    Here is a standalone class that you can use instead XRController
    Code (CSharp):
    1. public class OculusController : XRController
    2. {
    3.     private InputDevice _headInputDevice;
    4.     private TrackedPoseDriver.TrackingType _trackingType;
    5.  
    6.     private InputDevice HeadInputDevice
    7.     {
    8.         get
    9.         {
    10.             return _headInputDevice.isValid
    11.                 ? _headInputDevice
    12.                 : (_headInputDevice = InputDevices.GetDeviceAtXRNode(XRNode.CenterEye));
    13.         }
    14.     }
    15.  
    16.     private void Start()
    17.     {
    18.         var trackedPoseDriver = FindObjectOfType<TrackedPoseDriver>();
    19.         _trackingType = trackedPoseDriver.trackingType;
    20.     }
    21.  
    22.     protected override void OnBeforeRender()
    23.     {
    24.         //No way to check if enabled as m_UpdateTrackingType is private
    25.         UpdateTrackingInputOverride();
    26.     }
    27.  
    28.     private void LateUpdate()
    29.     {
    30.         UpdateTrackingInputOverride();
    31.     }
    32.  
    33.     private void UpdateTrackingInputOverride()
    34.     {
    35.         if (_trackingType != TrackedPoseDriver.TrackingType.RotationOnly) return;
    36.        
    37.         //Try to get device position
    38.         if (!inputDevice.TryGetFeatureValue(CommonUsages.devicePosition, out var devicePosition)) return;
    39.        
    40.         //Try to get center eye position
    41.         if (HeadInputDevice.TryGetFeatureValue(CommonUsages.centerEyePosition, out var centerEyePosition))
    42.         {
    43.             transform.localPosition = devicePosition - centerEyePosition;
    44.         }
    45.     }
    46. }
     
    Last edited: Aug 31, 2020
  2. kazak_tm

    kazak_tm

    Joined:
    Sep 7, 2021
    Posts:
    12
    Hi! Have you ever encountered the problem of incorrect input of rays? I'm trying to make a proper Ray Interaction with your script. But if I change the position of the head, the ray breaks.