Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

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:
    1
    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.
     
unityunity