Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice
  2. Ever participated in one our Game Jams? Want pointers on your project? Our Evangelists will be available on Friday to give feedback. Come share your games with us!
    Dismiss Notice

ARplane detection weirdness

Discussion in 'Handheld AR' started by mistergreen2016, Mar 3, 2020.

  1. mistergreen2016

    mistergreen2016

    Joined:
    Dec 4, 2016
    Posts:
    214
    I’m using ARfoundation 3.0.
    Say I’m scanning my floor and then my table. I have horizontal 2 planes of differing heights. I don’t scan for vertical planes. When I place an instantiated object using a ARraycast to detect a position. It will always find the table plane even though I’m aiming at the floor plane. So my object would be floating.

    it seems like the table plane is infinite and not restricted to the table. The visualize prefab looks like it should.
     
    Last edited: Mar 3, 2020
  2. mistergreen2016

    mistergreen2016

    Joined:
    Dec 4, 2016
    Posts:
    214
    Here's the code I'm using to get the position/Pose. I'm always using the first hit pose in the list assuming that's the one the ARraycast finds first.


    Code (CSharp):
    1. hits.Clear();
    2.             arRaycastManger.Raycast(screenCenter, hits, TrackableType.Planes);
    3.        
    4.             placementPoseIsValid = hits.Count > 0;
    5.        
    6.             if (placementPoseIsValid)
    7.             {
    8.                 placementPose = hits[0].pose; // a position & rotation in space, on the plane/trackable
    9.  
    10.            
    11.                 var cameraForward = Camera.current.transform.forward;
    12.  
    13.                 bearing.x = cameraForward.x;
    14.                 bearing.y = 0; // 0
    15.                 bearing.z = cameraForward.z;
    16.                 var cameraBearing = bearing.normalized;
    17.                 placementPose.rotation = Quaternion.LookRotation(cameraBearing) * Quaternion.Euler(0, 180, 0);
    18.              
    19.                 placementIndicator.transform.position = placementPose.position;
    20.                 placementIndicator.transform.rotation = placementPose.rotation;
    21.  
    22.  
    23.             }
     
  3. todds_unity

    todds_unity

    Unity Technologies

    Joined:
    Aug 1, 2018
    Posts:
    147
    Please refer to the TrackableTypes documentation.

    TrackableTypes.Planes is equivalent to asking for any of the TrackableTypes.PlaneEstimated, TrackableTypes.PlaneWithinBounds, TrackableTypes.PlaneWithinInfinity, or TrackableTypes.PlaneWithinPolygon to be returned.
     
  4. mistergreen2016

    mistergreen2016

    Joined:
    Dec 4, 2016
    Posts:
    214
    Ahhh... Thanks!
     
    todds_unity likes this.
  5. highpockets

    highpockets

    Joined:
    Jan 17, 2013
    Posts:
    31
    Hello,

    I am doing an ARRaycast against TrackableTypes.Planes, which succeeds pretty much always, but when I try to get the TrackableID of ARRaycastHits[0], it’s returning null every time. How is that even possible? I’m trying to get the normal of the plane, to do a projection of a direction vector along the said plane from the projected 2D position of the camera on the plane to the hit position.

    Any ideas?? I’m going to try other plane types in the meantime, but I would imagine that each plane, regardless of the type, should have a TrackableID, correct?
     
  6. mistergreen2016

    mistergreen2016

    Joined:
    Dec 4, 2016
    Posts:
    214
    trackableid is a unique Id of the plane of type trackableid. Nothing to do with normals. Get the arraycasthit[0].pose.tranform.positon for position and I think arraycasthit[0].normal
     
  7. highpockets

    highpockets

    Joined:
    Jan 17, 2013
    Posts:
    31
    arraycasthit[0].normal is not the normal of the plane..

    I know the trackableid isn't a normal, but I needed to get the plane's ID in order to get the plane and then get the plane's normal because the hit normal does not return the direction I'm looking for. The issue was because some of the TrackableType.Planes do not have a unique ID. I changed my code to Raycast against 'TrackableTypes.PlaneWithinPolygon' and it is working as expected.

    I would like to know which TrackableType.Planes have a TrackableId if someone could shed some light on this, that would be great. I didn't come across any documentation that suggests any of the plane types don't have an ID, though I assume 'PlaneEstimated' might be the culprit. I'm going to do some more testing to find which plane types have IDs, though I think this info would be nice to have in the API, but maybe I missed it in there.
     
  8. highpockets

    highpockets

    Joined:
    Jan 17, 2013
    Posts:
    31
    Ok, so my assumption was correct.. 'TrackableType.PlaneEstimated' was the culprit. Now I just do the following and it works:

    Code (CSharp):
    1. raycastManager.Raycast(new Vector2(Screen.width / 2, Screen.height / 2), _hits, TrackableType.Planes);
    2.  
    3. if(_hits.Count > 0 && _hits[0].hitType != TrackableType.PlaneEstimated)
    **EDIT:** Another potentiality for getting the normal of the plane could be 'hits[0].pose.up', though I don't know if this would be reliable
     
    Last edited: Mar 31, 2020
  9. mistergreen2016

    mistergreen2016

    Joined:
    Dec 4, 2016
    Posts:
    214
    Pose.up should work if your plane is horizontal.

    you can raycast a specific plane type
    arRaycastManger.Raycast(screenCenter, hits, TrackableType.PlaneWithinBounds | TrackableType.PlaneWithinPolygon);
     
    Last edited: Apr 1, 2020
unityunity