Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Added object on vertical plane always rotated in ARCore

enter image description here

I am adding an image on vertical plane in Sceneform ARFragment. But it always get rotated. The code is working fine on horizontal plane. My code for placing images on vertical Plane is as follow:

arFragment.setOnTapArPlaneListener { hitResult: HitResult, 
                                         plane: Plane, 
                                   motionEvent: MotionEvent ->

    if(!isOnceTapedOnSurface) {
        val anchor = hitResult.createAnchor()
        val anchorNode = AnchorNode(anchor)
        anchorNode.setParent(arFragment.arSceneView.scene)

        andy = TransformableNode(arFragment.transformationSystem)

        if(plane.type == Plane.Type.VERTICAL) {
            val anchorUp = anchorNode.up
            andy.setLookDirection(Vector3.up(), anchorUp)
        }

        andy.setParent(anchorNode)
        andy.renderable = andyRenderable
        andy.select()

        // arFragment.arSceneView.planeRenderer.isVisible = false
        isOnceTapedOnSurface = true
    }
}
like image 282
Keval Shukla Avatar asked Jan 09 '19 09:01

Keval Shukla


People also ask

How to place a 3D object on the floor with Arcore?

Move around until ARCore detects some planes. Then, simply tap on the screen to place a 3D object at that position. The speed of the plane detection is incredible, especially if the floor has enough structure like in the screenshot seen below.

How to visualize planes and point clouds in Arcore?

The ARCore example contains a simple script to visualize planes, point clouds and to place the Android mascot. We’ll create a shorter version of the script here. Create a new empty game object and call it “Managers”. Add a new script component (call it PlaneVisualizationManager.cs) and copy the following code:

Can ARKit and ARCore detect vertical planes?

ARKit and ARCore can analyze the environment visible in the camera view and detect the location of horizontal planes such as tables, floors, or the ground. The ARKit and ARCore frameworks cannot however directly detect vertical planes such as walls.

How do I merge two table planes in Arcore?

In case ARCore later discovers that two previously separate planes grow together, they will be automatically merged. This could be the case if you for example scan the left side of a table, move your camera to the floor, then scan the right side of the table. ARCore creates two separate table planes.


2 Answers

To fix this issue you can use the above solution. But you should rotate an object using world rotation. Don't use local rotation. We need to zero the rotation value. If you are using local rotation, the object will behave anchor(parent) rotation. So by using world rotation we can control the object.

String planeType = "";

//When tapping on the surface you can get the anchor orientation

if (plane.getType() == Plane.Type.VERTICAL){
                planeType = "Vertical";
            }else if (plane.getType() == Plane.Type.HORIZONTAL_UPWARD_FACING){
                planeType = "Horizontal_Upward";
            }else if (plane.getType() == Plane.Type.HORIZONTAL_DOWNWARD_FACING){
                planeType = "Horizontal_Downward";
            }else {
                planeType = "Horizontal";
            }```


// First set object world rotation zero

transformableNode.setWorldRotation(Quaternion.axisAngle(new Vector3(0, 0f, 0), 0));


// check plane type is vertical or horizontal if it is vertical below logic will work.

if (planeType.equals("Vertical")) {

   Vector3 anchorUp = anchorNode.getUp();
   transformableNode.setLookDirection(Vector3.up(), anchorUp);

}
like image 111
surya nadiminti Avatar answered Sep 29 '22 01:09

surya nadiminti


To fix this issue you need to set public Pose getCenterPose(). It returns the pose of the center of the detected plane, defined to have the origin. The pose's transformed +Y axis will be point normal out of the plane, with the +X and +Z axes orienting the extents of the bounding rectangle.

anchor = mySession.createAnchor(plane.getCenterPose())

When the its trackable state is TRACKING, this pose is synced with the latest frame. When its trackable state is PAUSED, an identity pose will be returned.

Your code could be the following:

Anchor newAnchor;

for (Plane plane : mSession.getAllTrackables(Plane.class)) {

    if(plane.getType() == Plane.Type.VERTICAL && 
       plane.getTrackingState() == TrackingState.TRACKING) {
          newAnchor = plane.createAnchor(plane.getCenterPose());
          break;
    }
}

One more thing from Google ARCore software engineers:

Keep objects close to anchors.

When anchoring objects, make sure that they are close to the anchor you are using. Avoid placing objects farther than a few meters from the anchor to prevent unexpected rotational movement due to ARCore's updates to world space coordinates.

If you need to place an object more than a few meters away from an existing anchor, create a new anchor closer to this position and attach the object to the new anchor.

like image 27
Andy Jazz Avatar answered Sep 29 '22 02:09

Andy Jazz