diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 8861c61be9..6375dbee0d 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -6,8 +6,9 @@ A new header is inserted each time a *tag* is created. ## Next release - gltfio now supports simple instancing of entire assets. -- For improved performance, gltfio now threads more tasks and assumes assets are well-formed. +- gltfio has improved performance and assumes assets are well-formed. - gltfio now supports name and prefix lookup for entities. +- ModelViewer now allows resources to be fetched off the UI thread. - Add missing JavaScript API for `View::setVisibleLayers()`. - Add support for DOF with Metal backend. - SSAO now has an optional high(er) quality upsampler. diff --git a/android/filament-utils-android/src/main/java/com/google/android/filament/utils/ModelViewer.kt b/android/filament-utils-android/src/main/java/com/google/android/filament/utils/ModelViewer.kt index 1054218210..923cc4f4e6 100644 --- a/android/filament-utils-android/src/main/java/com/google/android/filament/utils/ModelViewer.kt +++ b/android/filament-utils-android/src/main/java/com/google/android/filament/utils/ModelViewer.kt @@ -16,6 +16,7 @@ package com.google.android.filament.utils +import android.os.AsyncTask import android.view.MotionEvent import android.view.Surface import android.view.SurfaceView @@ -162,6 +163,8 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener { /** * Loads a JSON-style glTF file and populates the Filament scene. + * + * The given callback is triggered for each requested resource. */ fun loadModelGltf(buffer: Buffer, callback: (String) -> Buffer) { destroyModel() @@ -176,6 +179,17 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener { } } + /** + * Loads a JSON-style glTF file and populates the Filament scene. + * + * The given callback is triggered from a worker thread for each requested resource. + */ + fun loadModelGltfAsync(buffer: Buffer, callback: (String) -> Buffer): ResourceTask { + destroyModel() + asset = assetLoader.createAssetFromJson(buffer) + return ReadAssetsTask(this, callback).execute() + } + /** * Sets up a root transform on the current model to make it fit into a unit cube. * @@ -281,6 +295,28 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener { return true } + class ReadAssetsTask(val viewer: ModelViewer, val callback: (String) -> Buffer) : ResourceTask() { + override fun doInBackground(vararg params: Unit?): Map { + val items = HashMap() + val resourceUris = viewer.asset!!.resourceUris + for (resourceUri in resourceUris) { + items[resourceUri] = callback(resourceUri) + } + return items + } + + override fun onPostExecute(result: Map) { + for ((uri, buffer) in result) { + viewer.resourceLoader.addResourceData(uri, buffer) + } + viewer.asset?.let { asset -> + viewer.resourceLoader.asyncBeginLoad(asset) + viewer.animator = asset.animator + asset.releaseSourceData() + } + } + } + inner class SurfaceCallback : UiHelper.RendererCallback { override fun onNativeWindowChanged(surface: Surface) { swapChain?.let { engine.destroySwapChain(it) } @@ -310,3 +346,5 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener { private val kDefaultObjectPosition = Float3(0.0f, 0.0f, -4.0f) } } + +typealias ResourceTask = AsyncTask> diff --git a/android/samples/sample-gltf-viewer/src/main/java/com/google/android/filament/gltf/MainActivity.kt b/android/samples/sample-gltf-viewer/src/main/java/com/google/android/filament/gltf/MainActivity.kt index b8c9374c40..7db4968ef5 100644 --- a/android/samples/sample-gltf-viewer/src/main/java/com/google/android/filament/gltf/MainActivity.kt +++ b/android/samples/sample-gltf-viewer/src/main/java/com/google/android/filament/gltf/MainActivity.kt @@ -80,9 +80,8 @@ class MainActivity : Activity() { input.read(bytes) ByteBuffer.wrap(bytes) } - modelViewer.loadModelGltf(buffer) { uri -> - readCompressedAsset("models/$uri") - } + + modelViewer.loadModelGltfAsync(buffer, { uri -> readCompressedAsset("models/$uri") }) modelViewer.transformToUnitCube() }