如何在不点击屏幕的情况下放置对象

Aka*_*hra 9 android arcore

我试图显示一个对象,而不使用ARCore点击屏幕.在Google提供的ARCore Sceneform的基本示例中,您需要在检测到曲面后点击屏幕.

我想实现它,AR显示对象而不点击屏幕.

Anchor newAnchor;

    for (Plane plane : mSession.getAllTrackables(Plane.class)) {
        if (plane.getType() == Plane.Type.HORIZONTAL_UPWARD_FACING
                && plane.getTrackingState() == TrackingState.TRACKING)
        {
            newAnchor = plane.createAnchor(plane.getCenterPose());
            break;
        }
    }
Run Code Online (Sandbox Code Playgroud)

我试过这个没有点击屏幕显示.

如果有人知道怎么做,请帮助我.提前致谢

Cli*_*nkz 8

虽然我建议你在用户点击时点击对象并点击他/她点击屏幕的位置,但你所要求的就是这样.(这个例子在Kotlin)

在开始放置对象之前,您需要创建一个ModelRenderable.@Nullable全局声明一个.

private var modelRenderable: ModelRenderable? = null

//Create the football renderable
ModelRenderable.builder()
                //get the context of the ARFragment and pass the name of your .sfb file
                .setSource(fragment.context, Uri.parse("FootBall.sfb"))
                .build()

                //I accepted the CompletableFuture using Async since I created my model on creation of the activity. You could simply use .thenAccept too.
                //Use the returned modelRenderable and save it to a global variable of the same name
                .thenAcceptAsync { modelRenderable -> this@MainActivity.modelRenderable = modelRenderable }
Run Code Online (Sandbox Code Playgroud)

编程的主要部分必须在框架的onUpdate方法上完成.所以你附加了一个像这样的帧更新的监听器

 fragment.arSceneView.scene.addOnUpdateListener(this@MainActivity) //You can do this anywhere. I do it on activity creation post inflating the fragment
Run Code Online (Sandbox Code Playgroud)

现在你处理在侦听器上添加一个对象.

 override fun onUpdate(frameTime: FrameTime?) {
    //get the frame from the scene for shorthand
    val frame = fragment.arSceneView.arFrame
    if (frame != null) {
        //get the trackables to ensure planes are detected
        val var3 = frame.getUpdatedTrackables(Plane::class.java).iterator()
        while(var3.hasNext()) {
            val plane = var3.next() as Plane

            //If a plane has been detected & is being tracked by ARCore
            if (plane.trackingState == TrackingState.TRACKING) {

                //Hide the plane discovery helper animation
                fragment.planeDiscoveryController.hide()


                //Get all added anchors to the frame
                val iterableAnchor = frame.updatedAnchors.iterator()

                //place the first object only if no previous anchors were added
                if(!iterableAnchor.hasNext()) {
                    //Perform a hit test at the center of the screen to place an object without tapping
                    val hitTest = frame.hitTest(frame.screenCenter().x, frame.screenCenter().y)

                    //iterate through all hits
                    val hitTestIterator = hitTest.iterator()
                    while(hitTestIterator.hasNext()) {
                        val hitResult = hitTestIterator.next()

                        //Create an anchor at the plane hit
                        val modelAnchor = plane.createAnchor(hitResult.hitPose)

                        //Attach a node to this anchor with the scene as the parent
                        val anchorNode = AnchorNode(modelAnchor)
                        anchorNode.setParent(fragment.arSceneView.scene)

                        //create a new TranformableNode that will carry our object
                        val transformableNode = TransformableNode(fragment.transformationSystem)
                        transformableNode.setParent(anchorNode)
                        transformableNode.renderable = this@MainActivity.modelRenderable

                        //Alter the real world position to ensure object renders on the table top. Not somewhere inside.
                        transformableNode.worldPosition = Vector3(modelAnchor.pose.tx(),
                                modelAnchor.pose.compose(Pose.makeTranslation(0f, 0.05f, 0f)).ty(),
                                modelAnchor.pose.tz())
                    }
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我使用了一种扩展方法

//A method to find the screen center. This is used while placing objects in the scene
private fun Frame.screenCenter(): Vector3 {
    val vw = findViewById<View>(android.R.id.content)
    return Vector3(vw.width / 2f, vw.height / 2f, 0f)
}
Run Code Online (Sandbox Code Playgroud)

这是最终结果 在此输入图像描述