首页 文章

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

提问于
浏览
2

我试图显示一个对象,而不使用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;
        }
    }

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

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

1 回答

  • 4

    虽然我建议你在用户点击时点击对象并点击屏幕上的点击,但你可以这样做 . (这个例子在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 }
    

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

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

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

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

    我使用了一种扩展方法

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

    这是最终结果
    enter image description here

相关问题