为什么增强图像场景 SDK 示例不适用于 运行 次构建的 AR 对象?

Why does the Augmented Image Sceneform SDK Sample doesn't work only with run-time constructed AR objects?

我正在修改 Sceneform SDK 的 Augmented Image sample code after I completed the accompanying code lab。完成的示例将两种类型的对象添加到 AR 场景中:一种是使用 CAD 软件建模并从 sfb 二进制文件(即绿色迷宫)加载,另一种是构建的红球 运行-时间使用MaterialFactoryShapeFactory.

一个简单的实验是去掉绿色的迷宫只剩下红色的球(当然还要去掉物理引擎)。然而在那种情况下,红球不会出现在 AR 场景中。

有趣的是绿色迷宫不必出现在场景中 - 我的意思是我不必创建 Node、分配可渲染等等 https://github.com/CsabaConsulting/sceneform-android-sdk/blob/master/samples/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/AugmentedImageNode.java#L139 :

mazeNode = new Node();
mazeNode.setParent(this);
mazeNode.setRenderable(mazeRenderable.getNow(null));

但是如果我把加载代码拿出来https://github.com/CsabaConsulting/sceneform-android-sdk/blob/master/samples/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/AugmentedImageNode.java#L89

mazeRenderable =
        ModelRenderable.builder()
                .setSource(context, Uri.parse("GreenMaze.sfb"))
                .build();

最重要的是 setImage 中的代码,它等待模型完全加载并构建 https://github.com/CsabaConsulting/sceneform-android-sdk/blob/master/samples/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/AugmentedImageNode.java#L125

if (!mazeRenderable.isDone()) {
  CompletableFuture.allOf(mazeRenderable)
          .thenAccept((Void aVoid) -> setImage(image))
          .exceptionally(
                  throwable -> {
                    Log.e(TAG, "Exception loading", throwable);
                    return null;
                  });
  return;
}

球不会出现。如果我去掉上面的这个 .isDone() 部分,球(以及我添加的任何其他 运行 时间构建的对象)将不会出现。我没有在 AR Session 或其他任何地方找到任何指示某些东西尚未准备好工作的指示器。在我的应用程序中,我可能只使用 运行 时间构建的 3D 对象,我是否需要 sfb 只是为了那些出现的对象?

发生这种情况是因为隐式地基于工厂的场景构建也包含 CompletableFuture!更具体地说,material 建筑是 returns CompletableFuture.

的功能

没有意识到这一点,我没有引用问题中重要的代码部分。您可以看到 Maze 模型加载器说明的正下方:

https://github.com/CsabaConsulting/sceneform-android-sdk/blob/master/samples/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/AugmentedImageNode.java#L94

MaterialFactory.makeOpaqueWithColor(context, new Color(android.graphics.Color.RED))
  .thenAccept(
    material -> {
      ballRenderable =
        ShapeFactory.makeSphere(0.01f, new Vector3(0, 0, 0), material); });

在这里我们可以看到 .thenAccept( 的标志,它揭示了 makeOpaqueWithColor returns 一个 Future。虽然模型加载也在代码中,但我们稍后也进行了此检查:

if (!mazeRenderable.isDone()) {
  CompletableFuture.allOf(mazeRenderable)

不幸的是,该代码没有关注同样异步构建的 material。但是等待 3D 模型加载会提供足够的时间,以便 material 建筑物在访问时也可以完成。然而,一旦我将迷宫连同未来的服务员代码部分一起移除,就没有等待 material 建筑完成的保障。这导致在 material 实际准备好之前构建整个场景层次结构。这导致了一个看不见的场景。

https://github.com/googlecodelabs/arcore-augmentedimage-intro/issues/7