Estoy agregando una imagen en un plano vertical en Sceneform ARFragment. Pero siempre se rota. El código funciona bien en el plano horizontal. Mi código para colocar imágenes en el plano vertical es el siguiente:
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 } }Para solucionar este problema, puede utilizar la solución anterior. Pero debes rotar un objeto usando la rotación mundial. No utilice la rotación local. Necesitamos poner a cero el valor de rotación. Si está utilizando la rotación local, el objeto se comportará como una rotación de ancla (principal). Entonces, al usar la rotación mundial, podemos controlar el objeto.
String planeType = "";
//Al tocar la superficie puede obtener la orientación del ancla
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); }Para solucionar este problema, debe configurar
public Pose getCenterPose(). Devuelve la pose del centro del plano detectado, definido para tener el origen. El eje+Ytransformado de la pose será un punto normal fuera del plano, con los ejes+Xy+Zorientando las extensiones del rectángulo delimitador.
anchor = mySession.createAnchor(plane.getCenterPose()) Cuando su estado rastreable es TRACKING , esta pose se sincroniza con el último fotograma. Cuando su estado rastreable está PAUSED , se devolverá una pose de identidad.
Su código podría ser el siguiente:
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; } }Una cosa más de los ingenieros de software de Google ARCore :
Keep objects close to anchors.Al anclar objetos, asegúrese de que estén cerca del ancla que está utilizando. Evite colocar objetos a más de unos pocos metros del ancla para evitar movimientos de rotación inesperados debido a las actualizaciones de ARCore a las coordenadas del espacio mundial.
Si necesita colocar un objeto a más de unos pocos metros de un anclaje existente, cree un nuevo anclaje más cerca de esta posición y adjunte el objeto al nuevo anclaje.