augmented-realityarcoresceneformandroid-augmented-reality

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


I'm tinkering with the Sceneform SDK's Augmented Image sample code after I completed the accompanying code lab. The completed sample adds two types of objects to the AR scene: one is modeled with a CAD software and loaded from an sfb binary (that's the green maze) and the other one is a red ball which is constructed run-time using the MaterialFactory and ShapeFactory.

A simple experiment is to remove the green maze to only have the red ball (and remove the physics engine of course as well). In that case however the red ball does not appear on the AR scene.

The interesting thing is that the green maze does not have to appear on the scene - by that I mean I don't have to create the Node, assign renderable, etc. 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));

But if I take out the loading code 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();

and most importantly the code in the setImage which waits until the model is fully loaded and built 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;
}

The ball won't appear. The ball (and any other run-time constructed objects I add) won't appear if I take out this .isDone() section above. I haven't found any indicator in the AR Session or anywhere else which would indicate that something is not ready to work yet. In my application I may only use run-time built 3D objects, do I need an sfb only for the sake of those appearing?


Solution

  • This happened because implicitly the Factory based scene building contains CompletableFuture as well! More specifically the material building is a function which returns CompletableFuture.

    Not realizing this, I haven't quoted the important code section in the question. You can see that the just below the Maze model loader instructions:

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

    Here we can see the tell-tale sign of .thenAccept( which reveals that makeOpaqueWithColor returns a Future. While the model loading was also in the code we also had this check later:

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

    That code unfortunately doesn't pay attention to the material which is also asynchronously built. But the wait for the 3D model load gives enough time so that the material building can finish as well when it is accessed. However as soon as I removed the maze together with the future waiter code section, there was no safeguard for waiting for the material building to finish. This caused the whole scene hierarchy to be constructed before the material actually is ready. This results in an invisible scene.

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