Search Unity

AR Foundation - Align ar-object pararell to floor

Discussion in 'AR' started by heyfrey, Jun 23, 2019.

  1. heyfrey

    heyfrey

    Joined:
    Jun 26, 2018
    Posts:
    7
    i'm working with the new ar-foundation-samples and facing a problem with the ar-object rotation when i place it on a vertical plane. If i build the exactly same scene (SampleUXScene) to both platforms (iOS & Android)...so on iOS it's working like expected (see picture "what i want") and on Android something went wrong like on the picture "what i get". The up-vector is facing the Camera but it rotates also around the up-vector-axis!
    The same happens also placing an object on a horizontal plane!
    So what's the difference between iOS and Android? Is Android or ArCore interpreting something wrong? Because on iOS it's working correctly! Any ideas how to fix this problem?

    What i want:


    What i get:


    This is the code to place an object on a plane...
    Code (CSharp):
    1. void Update()
    2.     {
    3.         if (Input.touchCount > 0)
    4.         {
    5.             Touch touch = Input.GetTouch(0);
    6.  
    7.             if (touch.phase == TouchPhase.Began)
    8.             {
    9.                 if (m_RaycastManager.Raycast(touch.position, s_Hits, TrackableType.PlaneWithinPolygon))
    10.                 {
    11.                     Pose hitPose = s_Hits[0].pose;
    12.                
    13.                     spawnedObject = Instantiate(m_PlacedPrefab, hitPose.position, hitPose.rotation);
    14.                
    15.  
    16.                     if (onPlacedObject != null)
    17.                     {
    18.                         onPlacedObject();
    19.                     }
    20.                 }
    21.             }
    22.         }
    23.     }
     
    Last edited: Jul 3, 2019
  2. heyfrey

    heyfrey

    Joined:
    Jun 26, 2018
    Posts:
    7
  3. dnnkeeper

    dnnkeeper

    Joined:
    Jul 7, 2013
    Posts:
    84
    Try this:

    spawnedObject = Instantiate(m_PlacedPrefab, hitPose.position, Quaternion.LookRotation( hitPose.rotation * Vector3.forward, Vector3.up );

    Here's we are constructing a new rotation value for spawned object orienting it by pose forward and world up vectors.
     
    richard_revesz and Markus_T like this.
  4. Markus_T

    Markus_T

    Joined:
    Jan 23, 2014
    Posts:
    8
    I've recently had to face the same problem and here is my solution.

    I found that it actually takes 2 steps to get the picture onto the wall.
    1. You need to put the picture onto the plane found by AR Foundation.
    2. Then, rotate the picture so that it is parallel to the floor.
    My GetWallPlacement() method finds those two rotations.

    Here is my code. For the first part, replace what you have on your inner if statement (where you do the raycast) with my suggested if statement and that will call the method GetWallPlacement(...)

    One difference between your example and mine, is that my prefab has positive Z at the top of the picture and it looks like you had Z+ pointing down. I think you could probably adapt that for your needs by replacing Vector3.down in my method to Vector3.up.

    Code (CSharp):
    1.        
    2.         if (arRaycastManager.Raycast(touchPosition, hits, TrackableType.PlaneWithinPolygon))
    3.         {
    4.             Pose hitPose = hits[0].pose;
    5.             Quaternion orientation = Quaternion.identity;
    6.             Quaternion zUp = Quaternion.identity;
    7.  
    8.             GetWallPlacement(hits[0], out orientation, out zUp);
    9.  
    10.             GameObject wallObj = Instantiate(WallObject, hitPose.position, orientation);
    11.             wallObj.transform.rotation = zUp;
    12.         }
    13.  
    14.     private void GetWallPlacement(ARRaycastHit _planeHit, out Quaternion orientation, out Quaternion zUp)
    15.     {
    16.         TrackableId planeHit_ID = _planeHit.trackableId;
    17.         ARPlane planeHit = arPlaneManager.GetPlane(planeHit_ID);
    18.         Vector3 planeNormal = planeHit.normal;
    19.         orientation = Quaternion.FromToRotation(Vector3.up, planeNormal);
    20.         Vector3 forward = _planeHit.pose.position - (_planeHit.pose.position + Vector3.down);
    21.         zUp = Quaternion.LookRotation(forward, planeNormal);
    22.     }
    23.  
     
    jlhernandezm, zntuff, ROBYER1 and 2 others like this.
  5. CJRobertson932

    CJRobertson932

    Joined:
    Jul 11, 2016
    Posts:
    6
    The solution @Markus_T provided worked for me.
     
    unnanego likes this.