在垂直平面上添加的对象始终在ARCore

时间:2019-01-09 09:07:23

标签: android kotlin arcore sceneform

enter image description here

我正在Sceneform ARFragment中的垂直平面上添加图像。但是它总是旋转的。该代码在水平面上工作正常。我在垂直平面上放置图像的代码如下:

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
    }
}

2 个答案:

答案 0 :(得分:2)

要解决此问题,您可以使用上述解决方案。但是您应该使用世界旋转来旋转对象。不要使用本地轮换。我们需要将旋转值归零。如果您使用局部旋转,对象将表现锚(父)旋转。所以通过使用世界旋转我们可以控制对象。

String planeType = "";

//点击表面时可以获得锚点方向

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);

}

答案 1 :(得分:0)

  

要解决此问题,您需要设置public Pose getCenterPose()。它返回定义为具有原点的检测平面中心的姿态。姿势的变换后的+Y轴将垂直于平面,而+X+Z轴将边界矩形的范围定向。

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

当其可跟踪状态为TRACKING时,此姿势将与最新帧同步。当其可跟踪状态为PAUSED时,将返回一个身份姿势。

您的代码可能如下:

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;
    }
}
  

Google ARCore软件工程师的另一件事

     

Keep objects close to anchors

     

锚定对象时,请确保它们靠近您正在使用的锚点。避免将物体放置在距离锚点几米远的地方,以防止由于ARCore更新世界空间坐标而导致意外的旋转运动。

     

如果您需要将对象放置在距现有锚点几米远的地方,请在此位置附近创建一个新的锚点,然后将该对象附加到新的锚点上。

希望这会有所帮助。