当前位置: 首页 > 知识库问答 >
问题:

使用ArCore将对象动态放置在用户面前

娄学文
2023-03-14

我正在使用ArCore为Android构建一个简单的导航应用程序(Java)。我开始在Google(https://github.com/google-ar/sceneform-android-sdk/tree/master/samples/hellosceneform)的场景表单演示上构建我的应用程序。

目前,该应用程序正在扫描环境中的锚点。用户可以通过点击锚点将对象放置在锚点上。是否可以使用这些找到的锚点自动放置一个箭头,例如在用户面前导航?箭头可能应该3m-5m在用户面前,如果用户接近,则移动。

我知道如何查看锚点并始终删除最后一个锚点。但是我不确定如何将下一个对象自动放置在用户面前。有办法做到这一点吗?

编辑:没有办法吗?也许可以从锚点读出位置,并用所需的距离进行查找?

共有2个答案

郭麒
2023-03-14

下面是将对象放置在屏幕中央的代码段

    override fun onUpdate(frameTime: FrameTime?) {
    arFragment?.let { fragment ->
        fragment.arSceneView?.let { sceneView ->
            sceneView.arFrame?.let { frame ->
                if (!placed) {
                    val trackable = frame.getUpdatedTrackables(Plane::class.java).iterator()
                    if (trackable.hasNext()) {
                        val plane = trackable.next() as Plane
                        if (plane.trackingState == TrackingState.TRACKING) {
                            fragment.planeDiscoveryController?.hide()
                            val hitTest =
                                frame.hitTest(frame.screenCenter().x, frame.screenCenter().y)
                            val hitTestIterator = hitTest.iterator()
                            if (hitTestIterator.hasNext()) {
                                val hitResult = hitTestIterator.next()
                                val modelAnchor = plane.createAnchor(hitResult.hitPose)
                                val anchorNode = AnchorNode(modelAnchor)
                                anchorNode.setParent(sceneView.scene)

                                val transformableNode =
                                    TransformableNode(fragment.transformationSystem)
                                transformableNode.setParent(anchorNode)
                                transformableNode.renderable = this@ARActivity.modelRenderable

                                transformableNode.worldPosition = Vector3(
                                    modelAnchor.pose.tx(),
                                    modelAnchor.pose.compose(
                                        Pose.makeTranslation(
                                            0f,
                                            0.05f,
                                            0f
                                        )
                                    ).ty(),
                                    modelAnchor.pose.tz()
                                )
                                placed = true
                            }
                        }
                    }
                }
            }
        }
    }
}

private fun Frame.screenCenter(): Vector3 {
    val vw = findViewById<View>(android.R.id.content)
    return Vector3(vw.width / 2f, vw.height / 2f, 0f)
}
燕雨石
2023-03-14

我希望这就是你想要的。一旦AR场景开始跟踪特征点,这将渲染手机前面的箭头。

//添加一个布尔值以确保只呈现1个箭头。

 boolean placed = false;

//在onCreate函数中添加更新侦听器,因为应用程序需要一两秒钟才能获取相机的姿势,如果您尝试从空姿势制作锚点,应用程序可能会崩溃。

arFragment.getArSceneView().getScene().addOnUpdateListener(this::onUpdateFrame);

//您可以在更新功能中获得相机的姿势,从而在相机前面相应地定位。

private void onUpdateFrame(FrameTime frameTime) {

    Frame frame = arFragment.getArSceneView().getArFrame();

    // If there is no frame, just return.
    if (frame == null) {
        return;
    }

  //Making sure ARCore is tracking some feature points, makes the augmentation little stable. 
  if(frame.getCamera().getTrackingState()==TrackingState.TRACKING && !placed) {

      Pose pos = frame.getCamera().getPose().compose(Pose.makeTranslation(0, 0, -0.3f));
      Anchor anchor = arFragment.getArSceneView().getSession().createAnchor(pos);
      AnchorNode anchorNode = new AnchorNode(anchor);
      anchorNode.setParent(arFragment.getArSceneView().getScene());

  // Create the arrow node and add it to the anchor.
  Node arrow = new Node();
  arrow.setParent(anchorNode);
  arrow.setRenderable(arrowRenderable);
  placed = true; //to place the arrow just once.

  }

}

您必须对箭头的变换进行更改,以将其精确地设置在摄像机前面的中心位置和正确的方向。我希望这能让你开始。干杯

 类似资料:
  • 我正在开发一个AR导航应用程序,但我对它的AR方面并不太熟悉。是否可以将物体放置在静态位置,例如屏幕的一角? 我的应用程序基于谷歌的场景形式示例:https://github.com/google-ar/sceneform-android-sdk/tree/master/samples/hellosceneform.我已经导入了我想要使用的3D模型。目前,该应用程序正在寻找可以放置对象的锚。我只想

  • 我陷入了一个问题,需要在反序列化过程中使用和将解析对象的引用设置为其子对象。 为了描述这个问题,下面是类结构的简单表示。 通过这种结构,我可以通过向我的 提供 来在 中设置,例如: 我知道,我可以添加额外的到我的,但我不知道如何提供我的对象的引用,该对象正在被解析(即时)到对象? 任何帮助将不胜感激!

  • 我一直在看代码实验室的场景形式介绍示例。一切正常,但我也想检测单个(固体)彩色平面。据我所知,ARcore只能检测带有某些图案或强烈对比墙面的平面。是否有任何方法可以检测单个颜色平面或手动方式将对象放置在单个颜色平面上,并使用对象的所有其他控件(旋转,移动)?

  • 问题内容: 嗨,我将以下结构嵌套在一个更大的结构中,该结构是通过api调用返回的,但是我无法对这部分进行编码/解码。我遇到的问题是customKey和customValue都是动态的。 我尝试了类似的操作,但是显然不起作用,因为它实际上不是的数组。 问题答案: 由于您将我的答案链接到另一个问题,因此我将扩展该问题以回答您的问题。 事实是,如果您知道要查找的位置,那么所有键在运行时都是已知的: 用法

  • 问题内容: 我正在构建一个API应用程序,该应用程序实质上允许用户构建一个文档,该文档可以按他们想要的方式进行结构化,并将存储在Elasticsearch中。本质上,我为用户提供了一个简单的界面来访问我们的Elasticsearch实例。我试图使实现尽可能简单。到目前为止,这是我要处理的内容。 预期主体的对象: 简单实施: 这可以正常工作,但它在源中包含索引,类型和ID。我真正想做的只是在建立索引

  • 问题内容: 我在另一个实现Parcelable的场所对象中有一个Location对象。我该如何在我的writeToParcel方法实现中正确序列化它?所以这是一些代码: 问题答案: 在这里,您有一个片段如何将可分割对象序列化为您自己的包裹。