如何将 AR 中的 3D 模型放置在屏幕中心,并将其相对于轴上的相机角度移动近或远?

San*_*mar 6 android arcore sceneform

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

Camera camera = arSceneView.getScene().getCamera();
            Vector3 distance = Vector3.subtract(camera.getWorldPosition(), vector3CirclePosition);
            float abs = Math.abs(distance.y);
            float newAngleInRadian = (float) (Math.toRadians(90f) - (float) camera.getLocalRotation().x);
            float zCoordinate = (float) (abs / Math.cos(newAngleInRadian));
            Log.i("1", "zCoordinate::" + zCoordinate + "::" + abs);
            Vector3 cameraPos = arFragment.getArSceneView().getScene().getCamera().getWorldPosition();
            Vector3 cameraForward = arFragment.getArSceneView().getScene().getCamera().getForward();
            Vector3 position = Vector3.add(cameraPos, cameraForward.scaled(zCoordinate));
            redNodeCenter.setWorldPosition(position);
Run Code Online (Sandbox Code Playgroud)

Ran*_*mar 0

第 1 步:在类中创建 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
    }
}
Run Code Online (Sandbox Code Playgroud)

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

  arSceneView.scene.addOnUpdateListener { addWaterMark() }
Run Code Online (Sandbox Code Playgroud)

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

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

  camera.screenPointToRay(200f,500f)//200f -> X position, 500f -> Y position
Run Code Online (Sandbox Code Playgroud)