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

AR Foundation all planes register as Horizontal

Discussion in 'AR' started by enhawk, Nov 15, 2018.

  1. enhawk

    enhawk

    Joined:
    Aug 22, 2013
    Posts:
    833
    using

    Code (CSharp):
    1. ARPlane thisPlane = arpm.TryGetPlane(eventArgs.Plane.Id);
    2.  
    3.         if (thisPlane.boundedPlane.Alignment == PlaneAlignment.Vertical)
    4.         {
    5.             print("vertical");
    6.         }
    this never registers as vertical, even if they are vertical planes
     
  2. tdmowrer

    tdmowrer

    Joined:
    Apr 21, 2017
    Posts:
    605
    What do you get if you just print out the Alignment?

    eventArgs.Plane is a BoundedPlane, so you should just use that directly rather than asking the ARPlaneManager for its copy. The ARPlaneManager component subscribes to the ARSubsystemManager's plane events, which it then uses to update the ARPlane components in the scene. One possible explanation for what you're seeing is
    1. PlaneAddedEvent fires
    2. Your logic runs, which grabs asks the ARPlaneManager for its copy of the BoundedPlane
    3. The ARPlaneManager receives the PlaneAddedEvent and updates each ARPlane's BoundedPlane.

    So you may be getting at the plane before the ARPlaneManager has updated the ARPlane.

    Another option would be to instead subscribe to the ARPlaneManager's plane events, which additionally gives you the ARPlane.
     
  3. enhawk

    enhawk

    Joined:
    Aug 22, 2013
    Posts:
    833
    The horizontal ones print out as horizontal, the vertical ones come out as nonaxis
     
  4. tdmowrer

    tdmowrer

    Joined:
    Apr 21, 2017
    Posts:
    605
    Ah, that sounds more like it. We added this enum before ARCore and ARKit actually supported vertical planes, so we're making the determination by computing the angle of the normal with the horizontal. I've found ARKit can vary by 6 or 7 degrees from perfectly vertical, so that calculation seems to be too restrictive.

    NonAxis (as in not axis aligned) just means it isn't perfectly vertical or horizontal. Since neither ARCore or ARKit support that, you could just assume NonAxis is the same as vertical for now.

    You could also perform the calculation yourself, and allow for greater variance in vertical planes. The calculation we're doing is equivalent to

    Code (CSharp):
    1. if (Mathf.Abs(plane.normal.y) <= epsilon) // assume vertical
    Where epsilon is a small number. The y component of the normal is the cosine of the angle it makes with the up vector, so to find a reasonable value, take the inverse cosine. If
    epsilon == 0.0
    , that would be 90 degrees (so a perfectly vertical plane), while an epsilon of 0.1 would be plus or minus 6 degrees (since arccos(0.1) = 84.2 degrees).
     
    Markus_T likes this.
  5. Mal_Duffin

    Mal_Duffin

    Joined:
    Jan 22, 2015
    Posts:
    71
    Just out of curiosity, does this mean that the IgnoreVerticalPlanes sample scene never worked?

    It uses the code...

    Code (CSharp):
    1. if (plane.boundedPlane.Alignment == PlaneAlignment.Vertical)
    This issue seems to have been reported a while back ( https://forum.unity.com/threads/bou...ing-ar-foundation-on-ios.558589/#post-3701575 ), but didn't get a reply.

    It would be great if the built-in tolerance for PlaneAlignment.Vertical was the same as it currently is for PlaneAlignment.Horizontal ( and was configurable - better still, allow for both tolerances to have separate values ).

    At the very least, the sample scene should be updated to work using the normal.y check.
     
    enhawk and newguy123 like this.
  6. tdmowrer

    tdmowrer

    Joined:
    Apr 21, 2017
    Posts:
    605
    It worked when I tested it, but it is possible for some vertical planes to slip through. I've added a way to request only horizontal or vertical plane detection for the next release of ARFoundation, which will eliminate the need for this sample.
     
    assassinKK likes this.
  7. assassinKK

    assassinKK

    Joined:
    Dec 14, 2016
    Posts:
    2
    Also, we should be able to request only ground horizontal planes. As of now, you cannot disable ceiling detection.
     
  8. Tarrag

    Tarrag

    Joined:
    Nov 7, 2016
    Posts:
    215
    I tried https://github.com/Unity-Technologi...aster/Assets/Scripts/DisableVerticalPlanes.cs
    Despite vertical planes may be disabled it appears the raycast and placement of objects is successful. Anyone else seeing this behaviour?

    I had to add these lines inside the raycast condition to make it work at cost of performance:
    Code (CSharp):
    1. if(m_ArRaycastManagerScript.Raycast(ray, s_Hits, TrackableType.PlaneWithinPolygon))
    2.             {
    3.                 TrackableId planeHit_ID = s_Hits[0].trackableId;
    4.                 ARPlane m_ARPlaneHit = m_PlaneManagerScript.GetPlane(planeHit_ID);
    5.            
    6.                 if (m_ARPlaneHit.alignment.ToString().Equals("NotAxisAligned") || m_ARPlaneHit.alignment.ToString().Equals("Vertical") || m_ARPlaneHit.alignment.ToString().Equals("None"))
    7.                 {
    8.                     Debug.Log("Exiting raycast, plane is " + m_ARPlaneHit.alignment +" in string " + m_ARPlaneHit.alignment.ToString() + " is on/off:"+m_ARPlaneHit.gameObject.activeSelf);
    9.                     return;
    10.                 }
     
    junaid109 likes this.
  9. Thimo_

    Thimo_

    Joined:
    Aug 26, 2019
    Posts:
    59
    Is it possible to determine the difference between a horizontal groundplane facing upward (groundplane) and a horizontal plane facing downward (ceiling)?
     
  10. tdmowrer

    tdmowrer

    Joined:
    Apr 21, 2017
    Posts:
    605
    The PlaneAlignment enum differentiates between upward and downward facing planes.

    Edit: Get a plane's alignment with ARPlane.alignment
     
    Markus_T likes this.
  11. Markus_T

    Markus_T

    Joined:
    Jan 23, 2014
    Posts:
    8
    The PlaneAlignment enum seems to work fine. You can use this method to test this and also get the rotation you need to orient any object you're placing to match the orientation of the found plane.

    The colour just lets you set the colour of the object you're placing so that you can see that it's working properly.

    Code (CSharp):
    1.  
    2. private Quaternion GetRotation(ARRaycastHit _planeHit, out Color _planeColor)
    3.     {
    4.         TrackableId planeHit_ID = _planeHit.trackableId;
    5.         ARPlane planeHit = arPlaneManager.GetPlane(planeHit_ID);
    6.         Vector3 planeNormal = planeHit.normal;
    7.         Quaternion orientToPlane = Quaternion.FromToRotation(Vector3.up, planeNormal);
    8.  
    9.         switch (planeHit.alignment)
    10.         {
    11.             case PlaneAlignment.HorizontalDown:
    12.                 _planeColor = Color.blue;
    13.                 break;
    14.             case PlaneAlignment.Vertical:
    15.                 _planeColor = Color.green;
    16.                 break;
    17.             case PlaneAlignment.HorizontalUp:
    18.                 _planeColor = Color.red;
    19.                 break;
    20.             default:
    21.                 _planeColor = new Color(1f, 0f, 1f, 1f);
    22.                 break;
    23.         }
    24.  
    25.  
    26.         return orientToPlane;
    27.     }
    28.  
     
    Last edited: Feb 12, 2020