From 4d7b6602f24cab1b46a739e80d1b288818a58555 Mon Sep 17 00:00:00 2001 From: tpsiaki Date: Thu, 26 Mar 2020 18:55:49 -0700 Subject: [PATCH] Fix glTF loading in with Filament gltfio in Sceneform 1.16 (#1029) * Fix support for standard glTF which was broken (only glb worked). * Use correct Resource Loader for Filament gltf loads. --- .../LoadRenderableFromFilamentGltfTask.java | 25 ++++++------------- .../rendering/RenderableInstance.java | 8 +++--- .../RenderableInternalFilamentAssetData.java | 1 + 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/sceneformsrc/sceneform/src/main/java/com/google/ar/sceneform/rendering/LoadRenderableFromFilamentGltfTask.java b/sceneformsrc/sceneform/src/main/java/com/google/ar/sceneform/rendering/LoadRenderableFromFilamentGltfTask.java index d0015cb4..2c6a1d0c 100644 --- a/sceneformsrc/sceneform/src/main/java/com/google/ar/sceneform/rendering/LoadRenderableFromFilamentGltfTask.java +++ b/sceneformsrc/sceneform/src/main/java/com/google/ar/sceneform/rendering/LoadRenderableFromFilamentGltfTask.java @@ -49,9 +49,7 @@ public CompletableFuture downloadAndProcessRenderable( // Download byte buffer via thread pool () -> { try { - byte[] gltfByteBuffer = - SceneformBufferUtils.inputStreamCallableToByteArray(inputStreamCreator); - return ByteBuffer.wrap(gltfByteBuffer); + return SceneformBufferUtils.inputStreamCallableToByteArray(inputStreamCreator); } catch (Exception e) { throw new CompletionException(e); } @@ -59,7 +57,12 @@ public CompletableFuture downloadAndProcessRenderable( ThreadPools.getThreadPoolExecutor()) .thenApplyAsync( gltfByteBuffer -> { - this.renderableData.gltfByteBuffer = gltfByteBuffer; + // Check for glb header + this.renderableData.isGltfBinary = gltfByteBuffer[0] == 0x67 + && gltfByteBuffer[1] == 0x6C + && gltfByteBuffer[2] == 0x54 + && gltfByteBuffer[3] == 0x46; + this.renderableData.gltfByteBuffer = ByteBuffer.wrap(gltfByteBuffer); return renderable; }, ThreadPools.getMainExecutor()); @@ -92,19 +95,7 @@ static Uri getUriFromMissingResource( // Build uri to missing resource. String decodedMissingResPath = Preconditions.checkNotNull(decodedMissingResUri.getPath()); Uri decodedParentUri = Uri.parse(Uri.decode(parentUri.toString())); - String scheme = Preconditions.checkNotNull(decodedParentUri.getScheme()); - String authority = Preconditions.checkNotNull(decodedParentUri.getAuthority()); - String path = Preconditions.checkNotNull(decodedParentUri.getPath()); - // Remove root file - path = path.replace(Preconditions.checkNotNull(decodedParentUri.getLastPathSegment()), ""); - - Uri uri = - new Uri.Builder() - .scheme(scheme) - .authority(authority) - .path(path) - .appendPath(decodedMissingResPath) - .build(); + Uri uri = decodedParentUri.buildUpon().appendPath("..").appendPath(decodedMissingResPath).build(); // Normalize and return Uri. return Uri.parse(Uri.decode(URI.create(uri.toString()).normalize().toString())); } diff --git a/sceneformsrc/sceneform/src/main/java/com/google/ar/sceneform/rendering/RenderableInstance.java b/sceneformsrc/sceneform/src/main/java/com/google/ar/sceneform/rendering/RenderableInstance.java index 7145585b..f129098d 100644 --- a/sceneformsrc/sceneform/src/main/java/com/google/ar/sceneform/rendering/RenderableInstance.java +++ b/sceneformsrc/sceneform/src/main/java/com/google/ar/sceneform/rendering/RenderableInstance.java @@ -29,6 +29,7 @@ import java.nio.ByteBuffer; import java.nio.FloatBuffer; +import java.nio.IntBuffer; import java.util.concurrent.Callable; import java.util.function.Function; @@ -122,7 +123,8 @@ void createFilamentAssetModelInstance() { RenderableInternalFilamentAssetData.getMaterialProvider(), EntityManager.get()); - FilamentAsset createdAsset = loader.createAssetFromBinary(renderableData.gltfByteBuffer); + FilamentAsset createdAsset = renderableData.isGltfBinary ? loader.createAssetFromBinary(renderableData.gltfByteBuffer) + : loader.createAssetFromJson(renderableData.gltfByteBuffer); if (createdAsset == null) { throw new IllegalStateException("Failed to load gltf"); @@ -138,8 +140,6 @@ void createFilamentAssetModelInstance() { new Vector3(center[0], center[1], center[2])); } - ResourceLoader resourceLoader = new ResourceLoader(engine); - Preconditions.checkState(createdAsset.getResourceUris().length == 0); Function urlResolver = renderableData.urlResolver; for (String uri : createdAsset.getResourceUris()) { if (urlResolver == null) { @@ -149,7 +149,7 @@ void createFilamentAssetModelInstance() { Uri dataUri = urlResolver.apply(uri); try { Callable callable = LoadHelper.fromUri(renderableData.context, dataUri); - resourceLoader.addResourceData( + renderableData.resourceLoader.addResourceData( uri, ByteBuffer.wrap(SceneformBufferUtils.inputStreamCallableToByteArray(callable))); } catch (Exception e) { Log.e(TAG, "Failed to download data uri " + dataUri, e); diff --git a/sceneformsrc/sceneform/src/main/java/com/google/ar/sceneform/rendering/RenderableInternalFilamentAssetData.java b/sceneformsrc/sceneform/src/main/java/com/google/ar/sceneform/rendering/RenderableInternalFilamentAssetData.java index ebe628da..c564082a 100644 --- a/sceneformsrc/sceneform/src/main/java/com/google/ar/sceneform/rendering/RenderableInternalFilamentAssetData.java +++ b/sceneformsrc/sceneform/src/main/java/com/google/ar/sceneform/rendering/RenderableInternalFilamentAssetData.java @@ -27,6 +27,7 @@ public class RenderableInternalFilamentAssetData implements IRenderableInternalD Context context; Buffer gltfByteBuffer; + boolean isGltfBinary; ResourceLoader resourceLoader; @Nullable Function urlResolver; static MaterialProvider materialProvider;