Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Re-orient TrackedPoseDriver

Discussion in 'AR/VR (XR) Discussion' started by karmatha, Oct 11, 2017.

  1. karmatha

    karmatha

    Joined:
    Aug 25, 2012
    Posts:
    50
    Hi there,

    I'm trying to build a AR app using Google ARCore. The idea is to have a maze where the player can walk through (by physically walking). It works so far, the tracking works perfectly.

    However, the physical space is sometimes limited. For this reason I would like the user to touch the screen to stop rotational tracking. The user can then rotate themselves in such a way that there is sufficient space in front of them and keep walking. The code I'm using is as such:


    for (int i = 0; i < Input.touchCount; ++i){
    if (Input.GetTouch(i).phase == TouchPhase.Began){
    trackedPoseDriver.trackingType = TrackedPoseDriver.TrackingType.PositionOnly;​
    }

    if (Input.GetTouch(i).phase == TouchPhase.Ended){
    InputTracking.Recenter();
    trackedPoseDriver.trackingType = TrackedPoseDriver.TrackingType.RotationAndPosition;​
    }​
    }​

    When I touch the screen, the tracker will indeed stop rotating as intended. But when I release the screen it snaps back. How would I solve this?
     
  2. karmatha

    karmatha

    Joined:
    Aug 25, 2012
    Posts:
    50
    Woah I asked this question at π local time..
     
  3. Matt_D_work

    Matt_D_work

    Unity Technologies

    Joined:
    Nov 30, 2016
    Posts:
    202
    thats an interesting use case, Let me think about that one.

    in the meantime, can you do a device space reset in AR Core? EG: In most VR headsets you can ask the device to treat the current position as "0,0,0".
     
  4. mattrified_

    mattrified_

    Joined:
    Jul 17, 2013
    Posts:
    32
    I'm having this same issue. I tried creating a new class that inherits from TrackedPoseDriver and called CacheLocalPosition and then ResetToCachedLocalPosition but the new rotations aren't what I'd expect. The only thing I've been able to do is pause application and then reopen it does what I want it to do as if resetting the TrackedPoseDriver.
     
  5. Matt_D_work

    Matt_D_work

    Unity Technologies

    Joined:
    Nov 30, 2016
    Posts:
    202
    So, whats probably happening is that the "Cached" position is the world position that the camera started at in the scene. that, is then appended to the delta provided by your device.

    Hmm, thinking about this now.
     
    Last edited: Oct 18, 2017
  6. mattrified_

    mattrified_

    Joined:
    Jul 17, 2013
    Posts:
    32
    So I think I found a solution to both issues.
    Essentially, my problem is that if the player had to move, I wanted them to be able to "reset" the positioning of the game but not move the world position of any of the game objects for networking reasons. I took a suggestion from this post -- https://forum.unity.com/threads/setting-world-scale-without-affecting-physics.499671/ -- and moved the parent of my TrackedPoseDriver GameObject instead of the object itself.

    Code (csharp):
    1. // The position I want the camera to be in world space.
    2. Vector3 goalPosition;
    3.  
    4. // The forward I want the camera to be facing.
    5. Vector3 goalForward;
    6.  
    7. // Transform of the TrackedPosedDriver.
    8. Transform trackedPoseDriverTransform;
    9.  
    10. void Reset()
    11. {
    12.      Vector3 pos = trackedPoseDriverTransform.position;
    13.      Vector3 delta = goalPosition - pos;
    14.    
    15.      // Gets the forward of the trackedPoseDriver, but remove the Y value as we just want the heading.
    16.      Vector3 forward = trackedPoseDriverTransform.forward;
    17.      forward.y = 0;
    18.      forward.Normalize();
    19.      Quaternion rotDelta = Quaternion q = Quaternion.FromToRotation(trackedPoseDriverTransform.forward, goalForward);
    20.  
    21.      trackedPoseDriveTransform.parent.position += delta;
    22.      arTransform.parent.Rotate(0, q.eulerAngles.y, 0);
    23. }
    24.  
    There might be a better way to do the rotation delta part, but this was able to get the results I wanted.
     
    damayor11 likes this.
  7. mattrified_

    mattrified_

    Joined:
    Jul 17, 2013
    Posts:
    32
    Oh and two caveats.
    1. I am NOT doing any kind of plane tracking. This is just a simple game where you face forward and shoot at a target in the air.
    2. I find if I execute this method twice in a row, it's more accurate, probably due to an error in my math I'm not seeing.
     
  8. damayor11

    damayor11

    Joined:
    Oct 12, 2015
    Posts:
    3
    Thank you very much! I'm developing an XR app for Cardboard where I need to change the position but starting with a specific forward view. That worked in Unity with transform.lookAt(target) but doesn't work in the cardboard device if the c camera gameObject has a TrackedPoseDriver.
    Your -3 years old- post has helped me to reset and reorient the device. Thanks!!