From 2d4342607dbfc97b448f11afb321d44892aad6fc Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Wed, 16 Apr 2025 17:06:51 +0800 Subject: [PATCH] add async gltf resource loading --- .../viewer/src/ffi/src/ffi_filament_app.dart | 13 ++++++++++--- .../src/viewer/src/ffi/src/thermion_dart.g.dart | 16 ++++++++++++++-- .../native/include/c_api/TGltfResourceLoader.h | 4 +++- .../include/c_api/ThermionDartRenderThreadApi.h | 1 + .../native/src/c_api/TGltfResourceLoader.cpp | 17 +++++++++++++++++ 5 files changed, 45 insertions(+), 6 deletions(-) diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/ffi_filament_app.dart b/thermion_dart/lib/src/viewer/src/ffi/src/ffi_filament_app.dart index 62fdb7ae..83ca2407 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/ffi_filament_app.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/ffi_filament_app.dart @@ -787,9 +787,16 @@ class FFIFilamentApp extends FilamentApp { cb)); } if (loadResourcesAsync) { - // GltfResourceLoader_asyncBeginLoad(gltfResourceLoader) - throw UnimplementedError( - "TODO"); // need to use a NativeFinalizer to ensure the pointer is still valid until resource loader has finished + if(!GltfResourceLoader_asyncBeginLoad(gltfResourceLoader, filamentAsset)) { + throw Exception("Failed to begin async loading"); + } + GltfResourceLoader_asyncUpdateLoad(gltfResourceLoader); + + var progress = GltfResourceLoader_asyncGetLoadProgress(gltfResourceLoader); + while(progress < 1.0) { + GltfResourceLoader_asyncUpdateLoad(gltfResourceLoader); + progress = GltfResourceLoader_asyncGetLoadProgress(gltfResourceLoader); + } } else { final result = await withBoolCallback((cb) => GltfResourceLoader_loadResourcesRenderThread( diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart b/thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart index f7218c21..3fd351b9 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart @@ -2847,13 +2847,25 @@ external void GltfResourceLoader_destroy( ); @ffi.Native< - ffi.Void Function(ffi.Pointer, + ffi.Bool Function(ffi.Pointer, ffi.Pointer)>(isLeaf: true) -external void GltfResourceLoader_asyncBeginLoad( +external bool GltfResourceLoader_asyncBeginLoad( ffi.Pointer tGltfResourceLoader, ffi.Pointer tFilamentAsset, ); +@ffi.Native< + ffi.Void Function(ffi.Pointer)>(isLeaf: true) +external void GltfResourceLoader_asyncUpdateLoad( + ffi.Pointer tGltfResourceLoader +); + +@ffi.Native< + ffi.Double Function(ffi.Pointer)>(isLeaf: true) +external double GltfResourceLoader_asyncGetLoadProgress( + ffi.Pointer tGltfResourceLoader +); + @ffi.Native< ffi.Void Function(ffi.Pointer, ffi.Pointer, ffi.Pointer, ffi.Size)>(isLeaf: true) diff --git a/thermion_dart/native/include/c_api/TGltfResourceLoader.h b/thermion_dart/native/include/c_api/TGltfResourceLoader.h index 51056f7b..12067c72 100644 --- a/thermion_dart/native/include/c_api/TGltfResourceLoader.h +++ b/thermion_dart/native/include/c_api/TGltfResourceLoader.h @@ -10,7 +10,9 @@ extern "C" EMSCRIPTEN_KEEPALIVE TGltfResourceLoader *GltfResourceLoader_create(TEngine *tEngine, const char *relativeResourcePath); EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_destroy(TEngine *tEngine, TGltfResourceLoader *tGltfResourceLoader); -EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_asyncBeginLoad(TGltfResourceLoader *tGltfResourceLoader, TFilamentAsset *tFilamentAsset); +EMSCRIPTEN_KEEPALIVE bool GltfResourceLoader_asyncBeginLoad(TGltfResourceLoader *tGltfResourceLoader, TFilamentAsset *tFilamentAsset); +EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_asyncUpdateLoad(TGltfResourceLoader *tGltfResourceLoader); +EMSCRIPTEN_KEEPALIVE float GltfResourceLoader_asyncGetLoadProgress(TGltfResourceLoader *tGltfResourceLoader); EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_addResourceData(TGltfResourceLoader *tGltfResourceLoader, const char *uri, uint8_t *data, size_t length); EMSCRIPTEN_KEEPALIVE bool GltfResourceLoader_loadResources(TGltfResourceLoader *tGltfResourceLoader, TFilamentAsset *tFilamentAsset); diff --git a/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h b/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h index 938e1a2d..e42a0111 100644 --- a/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h +++ b/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h @@ -258,6 +258,7 @@ namespace thermion EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_destroyRenderThread(TEngine *tEngine, TGltfResourceLoader *tResourceLoader, void (*callback)()); EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_loadResourcesRenderThread(TGltfResourceLoader *tGltfResourceLoader, TFilamentAsset *tFilamentAsset, void (*callback)(bool)); EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_addResourceDataRenderThread(TGltfResourceLoader *tGltfResourceLoader, const char *uri, uint8_t *data, size_t length, void (*callback)()); + EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_asyncBeginLoadRenderThread(TGltfResourceLoader *tGltfResourceLoader, TFilamentAsset *tFilamentAsset, void (*callback)(bool)); EMSCRIPTEN_KEEPALIVE void GltfAssetLoader_loadRenderThread( TEngine *tEngine, diff --git a/thermion_dart/native/src/c_api/TGltfResourceLoader.cpp b/thermion_dart/native/src/c_api/TGltfResourceLoader.cpp index d3eaa96a..36aead93 100644 --- a/thermion_dart/native/src/c_api/TGltfResourceLoader.cpp +++ b/thermion_dart/native/src/c_api/TGltfResourceLoader.cpp @@ -69,6 +69,23 @@ EMSCRIPTEN_KEEPALIVE bool GltfResourceLoader_loadResources(TGltfResourceLoader * return gltfResourceLoader->loadResources(filamentAsset); } +EMSCRIPTEN_KEEPALIVE bool GltfResourceLoader_asyncBeginLoad(TGltfResourceLoader *tGltfResourceLoader, TFilamentAsset *tFilamentAsset) { + auto *gltfResourceLoader = reinterpret_cast(tGltfResourceLoader); + auto *filamentAsset = reinterpret_cast(tFilamentAsset); + return gltfResourceLoader->asyncBeginLoad(filamentAsset); +} + +EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_asyncUpdateLoad(TGltfResourceLoader *tGltfResourceLoader) { + auto *gltfResourceLoader = reinterpret_cast(tGltfResourceLoader); + gltfResourceLoader->asyncUpdateLoad(); +} + +EMSCRIPTEN_KEEPALIVE float GltfResourceLoader_asyncGetLoadProgress(TGltfResourceLoader *tGltfResourceLoader) { + auto *gltfResourceLoader = reinterpret_cast(tGltfResourceLoader); + return gltfResourceLoader->asyncGetLoadProgress(); +} + + #ifdef __cplusplus } }