如何将AnchorNode放置在屏幕中心并相对于摄像机移动和倾斜角度移动它?

时间:2019-06-24 14:44:15

标签: android arcore sceneform

下面是我尝试过的代码。它给了我想要的结果,但是并没有像camToPlan或MagicPlan app那样得到优化。在CamToPlan应用程序中,中心点根据摄像机的移动非常有效地移动。如果摄像机倾斜,则锚节点的距离会改变。如何在下面的代码中达到相同的目的?

    arFragment.setOnFrameListener((frameTime, frame) -> {
        if (cornerModel == null) {
            return;
        }
        if (frame == null) {
            return;
        }
        if (frame.getCamera().getTrackingState() != TrackingState.TRACKING) {
            isTracking = false;
            return;
        }
        if (frame.getCamera().getTrackingState() == TrackingState.TRACKING) {
            isTracking = true;
            if (isFloorCreated && mPlane != null) {
                Session session = arFragment.getArSceneView().getSession();
                if (session != null && anchorNodeCenter == null && transformableNodeCenter == null) {
                    anchorNodeCenter = new AnchorNode(session.createAnchor(mPlane.getCenterPose()));
                    anchorNodeCenter.setParent(scene);

                    transformableNodeCenter = new TransformableNode(arFragment.getTransformationSystem());
                    transformableNodeCenter.setParent(anchorNodeCenter);
                    transformableNodeCenter.setRenderable(centerModel);
                    transformableNodeCenter.getScaleController().setMaxScale(0.08f);
                    transformableNodeCenter.getScaleController().setMinScale(0.05f);
                    Quaternion rotation = Quaternion.axisAngle(new Vector3(0f, 1.0f, 0.0f), -90); // rotate x axis 90 degrees
                    transformableNodeCenter.setLocalRotation(rotation);
                    transformableNodeCenter.setWorldRotation(rotation);
                }
                if (transformableNodeCenter != null) {
                    Camera camera = scene.getCamera();
                    if (screenCenter == null)
                        screenCenter = getScreenCenter();
                    Ray ray = camera.screenPointToRay(screenCenter.x, screenCenter.y);

                    List<HitResult> hits;
                    hits = frame.hitTest(screenCenter.x, screenCenter.y);
                    if (hits != null && hits.size() > 0) {
                        HitResult hit = hits.get(hits.size() - 1);
                        Vector3 point = ray.getPoint(hit.getDistance());
                        Vector3 point1 = new Vector3(point.x, point.y, point.z);
                        transformableNodeCenter.setWorldPosition(point1);
                        addLineBetweenCenter(point1);
                    }
                }
            }
            for (Plane plane : frame.getUpdatedTrackables(Plane.class)) {

                if (anchorFloorCircle == null) {
                  //mPlane code goes here
                }
            }
        }

    });

1 个答案:

答案 0 :(得分:0)

第一步:在你的类中创建 addWaterMark() 方法

 private var oldWaterMark : Node? = null
 
 private fun addWaterMark() {
    ModelRenderable.builder()

            .setSource(context, R.raw.step1)
            .build()
            .thenAccept {
                addNode(it)
            }
            .exceptionally {
                Toast.makeText(context, "Error", Toast.LENGTH_SHORT).show()
                return@exceptionally null
            }

}

private fun addNode(model: ModelRenderable?) {
    if(oldWaterMark!=null){
        arSceneView().scene.removeChild(oldWaterMark)
    }
    model?.let {
        val node = Node().apply {
            setParent(arSceneView().scene)
            var camera = arSceneView().scene.camera

            var ray = camera.screenPointToRay(200f,500f)

           // var local=arSceneView.getScene().getCamera().localPosition

            localPosition = ray.getPoint(1f)
            localRotation = arSceneView().scene.camera.localRotation
            localScale = Vector3(0.3f, 0.3f, 0.3f)


            renderable = it
        }

        arSceneView().scene.addChild(node)
        oldWaterMark = node
    }
}

第 2 步:在 addOnUpdateListener 中调用 addWaterMark()

  arSceneView.scene.addOnUpdateListener { addWaterMark() }

注意:我创建了 oldWaterMark 对象来删除旧水印

如果你想改变位置改变这一行

  camera.screenPointToRay(200f,500f)//200f -> X position, 500f -> Y position