google-ar / sceneform-android-sdk

Sceneform SDK for Android
https://developers.google.com/sceneform/develop/
Apache License 2.0
1.23k stars 604 forks source link

Can't use Texture.Builder to load material from GLB file #824

Open kenyee opened 5 years ago

kenyee commented 5 years ago

Are there any limitations to what type of file can be loaded via the Texture Builder? I get this error:

java.util.concurrent.ExecutionException: java.lang.IllegalStateException: Failed to decode the texture bitmap. The InputStream was not a valid bitmap.

when I try to load: https://secure.img1-ag.wfcdn.com/docresources/0/166/1666848.glb using:

val textureBuilder = Texture.builder()
               .setSource(context, Uri.parse(url))
               .setUsage(Texture.Usage.DATA)
               .setSampler(
                       Texture.Sampler.builder()
                               .setMagFilter(Texture.Sampler.MagFilter.LINEAR)
                               .setMinFilter(Texture.Sampler.MinFilter.LINEAR_MIPMAP_LINEAR)
                               .build()
val material = MaterialFactory.makeOpaqueWithTexture(context, texture))
val cube = ShapeFactory.makeCube(frontFacingCubeSize, Vector3.zero(), material)

This article claims GLB files can be loaded by Sceneform now (we're on 1.11): https://medium.com/temy/dynamic-textures-in-sceneform-98d7a2d35406 I've also confirmed that the GLB file is valid by loading it into various GLB viewers and Blender and Sceneform can also load it as a model.

You can use this as a workaround though the material doesn't seem to tile properly on the cube and there doesn't seem to be way to set a sampler on the material to tile it:

fun loadTextureFromModel(url: String): CompletableFuture<Material> {
        // kinda hacky...return the first material from the model because the Texture.Builder doesn't work in ArCore 1.11.0
        val uri = Uri.parse(url)
        return loadModel(uri).thenApply { modelRenderable ->
            modelRenderable.material
        }
    }
    fun loadModel(uri: Uri): CompletableFuture<ModelRenderable> {
        validateUiThread()
        return ModelRenderable.builder()
                .setSource(
                        context, RenderableSource.builder().setSource(
                        context,
                        uri,
                        RenderableSource.SourceType.GLB
                ).build())
                .setRegistryId(uri)
                .build()
    }
smushy129 commented 5 years ago

seems related: https://github.com/google-ar/sceneform-android-sdk/issues/580