Динамически размещать объект перед пользователем с помощью ArCore - PullRequest
1 голос
/ 09 января 2020

Я использую ArCore для создания простого навигационного приложения для Android (в Java). Я начал создавать свое приложение на демонстрационной сцене из Google (https://github.com/google-ar/sceneform-android-sdk/tree/master/samples/hellosceneform).

В настоящее время приложение сканирует среду на наличие опорных точек. Пользователь может поместить объект в опорные точки, нажав на них. Можно ли использовать эти найденные точки привязки для автоматического размещения, например, стрелки для навигации перед пользователем? Стрелка должна находиться на расстоянии 3-5 метров от пользователя и двигаться, если пользователь приближается.

Я знаю, как просматривать точки привязки и всегда удалять последнюю привязку. Но я не уверен, как автоматически разместить следующий объект перед пользователем. Есть способ сделать это?

Редактировать: Нет ли способа сделать это? Может быть, зачитать позицию с якоря и искать с нужным расстоянием?

Ответы [ 2 ]

1 голос
/ 09 января 2020

Я надеюсь, что это то, что вы ищете. Это сделает стрелку перед телефоном, как только сцена AR начнет отслеживать характерные точки.

// Добавить логическое значение, чтобы обеспечить отображение только 1 стрелки.

 boolean placed = false;

// Добавить прослушиватель при обновлении в функции onCreate, так как для этого требуется se c или два для того, чтобы приложение получило позу камеры, и приложение может получить sh, если вы попытаетесь сделать привязку из нулевой позы.

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.

  }

}

Вам нужно будет внести изменения в преобразование стрелки, чтобы установить его точно в центре перед камерой и в правильной ориентации. Я надеюсь, это поможет вам начать. Ура!

0 голосов
/ 08 апреля 2020

Вот фрагмент кода для размещения объекта в центре экрана

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