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 7f0ae74c..39cf49e4 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 @@ -652,7 +652,7 @@ external ffi.Pointer SceneManager_getScene( @ffi.Native< EntityId Function(ffi.Pointer, ffi.Pointer, - ffi.Size, ffi.Bool, ffi.Int, ffi.Int)>(isLeaf: true) + ffi.Size, ffi.Bool, ffi.Int, ffi.Int, ffi.Bool)>(isLeaf: true) external int SceneManager_loadGlbFromBuffer( ffi.Pointer sceneManager, ffi.Pointer arg1, @@ -660,6 +660,7 @@ external int SceneManager_loadGlbFromBuffer( bool keepData, int priority, int layer, + bool loadResourcesAsync, ); @ffi.Native< @@ -1515,6 +1516,7 @@ external void remove_skybox_render_thread( ffi.Bool, ffi.Int, ffi.Int, + ffi.Bool, ffi.Pointer>)>( isLeaf: true) external void SceneManager_loadGlbFromBufferRenderThread( @@ -1525,6 +1527,7 @@ external void SceneManager_loadGlbFromBufferRenderThread( bool keepData, int priority, int layer, + bool loadResourcesAsync, ffi.Pointer> callback, ); diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart b/thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart index 409e1f0e..3cf8a614 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart @@ -5,8 +5,8 @@ import 'package:animation_tools_dart/animation_tools_dart.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_gizmo.dart'; import 'package:vector_math/vector_math_64.dart'; import 'package:vector_math/vector_math_64.dart' as v64; -import '../../../../utils/gizmo.dart'; -import '../../../../utils/matrix.dart'; +import '../../../../utils/src/gizmo.dart'; +import '../../../../utils/src/matrix.dart'; import '../../events.dart'; import '../../shared_types/view.dart'; import '../../thermion_viewer_base.dart'; @@ -546,7 +546,7 @@ class ThermionViewerFFI extends ThermionViewer { int numInstances = 1, bool keepData = false, int priority = 4, - int layer = 0}) async { + int layer = 0, bool loadResourcesAsync=false}) async { if (unlit) { throw Exception("Not yet implemented"); } @@ -557,7 +557,7 @@ class ThermionViewerFFI extends ThermionViewer { var entity = await withIntCallback((callback) => SceneManager_loadGlbFromBufferRenderThread(_sceneManager!, data.address, - data.length, numInstances, keepData, priority, layer, callback)); + data.length, numInstances, keepData, priority, layer, loadResourcesAsync, callback)); if (entity == _FILAMENT_ASSET_ERROR) { throw Exception("An error occurred loading GLB from buffer"); diff --git a/thermion_dart/lib/src/viewer/src/thermion_viewer_base.dart b/thermion_dart/lib/src/viewer/src/thermion_viewer_base.dart index 420f2393..0c8c5760 100644 --- a/thermion_dart/lib/src/viewer/src/thermion_viewer_base.dart +++ b/thermion_dart/lib/src/viewer/src/thermion_viewer_base.dart @@ -1,5 +1,5 @@ import 'package:thermion_dart/src/viewer/src/events.dart'; -import '../../utils/gizmo.dart'; +import '../../utils/src/gizmo.dart'; import 'shared_types/shared_types.dart'; export 'shared_types/shared_types.dart'; @@ -56,8 +56,10 @@ abstract class ThermionViewer { /// /// Render a single frame and copy the pixel buffer to [out]. /// - Future capture({covariant SwapChain? swapChain, - covariant View? view, covariant RenderTarget? renderTarget}); + Future capture( + {covariant SwapChain? swapChain, + covariant View? view, + covariant RenderTarget? renderTarget}); /// /// @@ -214,12 +216,16 @@ abstract class ThermionViewer { /// Specify [numInstances] to create multiple instances (this is more efficient than dynamically instantating at a later time). You can then retrieve the created instances with [getInstances]. /// If you want to be able to call [createInstance] at a later time, you must pass true for [keepData]. /// If [keepData] is false, the source glTF data will be released and [createInstance] will throw an exception. + /// If [loadResourcesAsync] is true, resources (textures, materials, etc) will + /// be loaded asynchronously (so expect some material/texture pop-in); + /// /// Future loadGlbFromBuffer(Uint8List data, {int numInstances = 1, bool keepData = false, int priority = 4, - int layer = 0}); + int layer = 0, + bool loadResourcesAsync}); /// /// Create a new instance of [entity]. diff --git a/thermion_dart/native/include/SceneManager.hpp b/thermion_dart/native/include/SceneManager.hpp index e486e4de..ef89e8c6 100644 --- a/thermion_dart/native/include/SceneManager.hpp +++ b/thermion_dart/native/include/SceneManager.hpp @@ -92,7 +92,7 @@ namespace thermion /// @return an Entity representing the FilamentAsset associated with the loaded FilamentAsset. /// EntityId loadGlb(const char *uri, int numInstances, bool keepData); - EntityId loadGlbFromBuffer(const uint8_t *data, size_t length, int numInstances = 1, bool keepData = false, int priority = 4, int layer = 0); + EntityId loadGlbFromBuffer(const uint8_t *data, size_t length, int numInstances = 1, bool keepData = false, int priority = 4, int layer = 0, bool loadResourcesAsync = false); EntityId createInstance(EntityId entityId); void remove(EntityId entity); diff --git a/thermion_dart/native/include/ThermionDartApi.h b/thermion_dart/native/include/ThermionDartApi.h index 20c37ac2..5a8586fc 100644 --- a/thermion_dart/native/include/ThermionDartApi.h +++ b/thermion_dart/native/include/ThermionDartApi.h @@ -202,7 +202,7 @@ extern "C" EMSCRIPTEN_KEEPALIVE TCamera* SceneManager_findCameraByName(TSceneManager* tSceneManager, EntityId entity, const char* name); EMSCRIPTEN_KEEPALIVE void SceneManager_setVisibilityLayer(TSceneManager *tSceneManager, EntityId entity, int layer); EMSCRIPTEN_KEEPALIVE TScene* SceneManager_getScene(TSceneManager *tSceneManager); - EMSCRIPTEN_KEEPALIVE EntityId SceneManager_loadGlbFromBuffer(TSceneManager *sceneManager, const uint8_t *const, size_t length, bool keepData, int priority, int layer); + EMSCRIPTEN_KEEPALIVE EntityId SceneManager_loadGlbFromBuffer(TSceneManager *sceneManager, const uint8_t *const, size_t length, bool keepData, int priority, int layer, bool loadResourcesAsync); EMSCRIPTEN_KEEPALIVE bool SceneManager_setMorphAnimation( TSceneManager *sceneManager, EntityId entity, diff --git a/thermion_dart/native/include/ThermionDartRenderThreadApi.h b/thermion_dart/native/include/ThermionDartRenderThreadApi.h index 967823f6..e2e31eea 100644 --- a/thermion_dart/native/include/ThermionDartRenderThreadApi.h +++ b/thermion_dart/native/include/ThermionDartRenderThreadApi.h @@ -52,7 +52,7 @@ extern "C" void load_skybox_render_thread(TViewer *viewer, const char *skyboxPath, void (*onComplete)()); void remove_skybox_render_thread(TViewer *viewer); - void SceneManager_loadGlbFromBufferRenderThread(TSceneManager *sceneManager, const uint8_t *const data, size_t length, int numInstances, bool keepData, int priority, int layer, void (*callback)(EntityId)); + void SceneManager_loadGlbFromBufferRenderThread(TSceneManager *sceneManager, const uint8_t *const data, size_t length, int numInstances, bool keepData, int priority, int layer, bool loadResourcesAsync, void (*callback)(EntityId)); void load_glb_render_thread(TSceneManager *sceneManager, const char *assetPath, int numInstances, bool keepData, void (*callback)(EntityId)); void load_gltf_render_thread(TSceneManager *sceneManager, const char *assetPath, const char *relativePath, bool keepData, void (*callback)(EntityId)); void create_instance_render_thread(TSceneManager *sceneManager, EntityId entityId, void (*callback)(EntityId)); diff --git a/thermion_dart/native/src/SceneManager.cpp b/thermion_dart/native/src/SceneManager.cpp index 8e4782c6..e87eb2bb 100644 --- a/thermion_dart/native/src/SceneManager.cpp +++ b/thermion_dart/native/src/SceneManager.cpp @@ -257,7 +257,7 @@ namespace thermion } - EntityId SceneManager::loadGlbFromBuffer(const uint8_t *data, size_t length, int numInstances, bool keepData, int priority, int layer) + EntityId SceneManager::loadGlbFromBuffer(const uint8_t *data, size_t length, int numInstances, bool keepData, int priority, int layer, bool loadResourcesAsync) { FilamentAsset *asset = nullptr; @@ -304,10 +304,18 @@ namespace thermion _gltfResourceLoader->asyncUpdateLoad(); } #else - if (!_gltfResourceLoader->loadResources(asset)) - { - Log("Unknown error loading glb asset"); - return 0; + if(loadResourcesAsync) { + if (!_gltfResourceLoader->asyncBeginLoad(asset)) + { + Log("Unknown error loading glb asset"); + return 0; + } + } else { + if (!_gltfResourceLoader->loadResources(asset)) + { + Log("Unknown error loading glb asset"); + return 0; + } } #endif diff --git a/thermion_dart/native/src/ThermionDartApi.cpp b/thermion_dart/native/src/ThermionDartApi.cpp index 6be98916..282804fe 100644 --- a/thermion_dart/native/src/ThermionDartApi.cpp +++ b/thermion_dart/native/src/ThermionDartApi.cpp @@ -169,7 +169,7 @@ extern "C" return ((SceneManager *)sceneManager)->loadGlb(assetPath, numInstances, keepData); } - EMSCRIPTEN_KEEPALIVE EntityId SceneManager_loadGlbFromBuffer(TSceneManager *sceneManager, const uint8_t *const data, size_t length, bool keepData, int priority, int layer) + EMSCRIPTEN_KEEPALIVE EntityId SceneManager_loadGlbFromBuffer(TSceneManager *sceneManager, const uint8_t *const data, size_t length, bool keepData, int priority, int layer, bool loadResourcesAsync) { return ((SceneManager *)sceneManager)->loadGlbFromBuffer((const uint8_t *)data, length, 1, keepData, priority, layer); } diff --git a/thermion_dart/native/src/ThermionDartRenderThreadApi.cpp b/thermion_dart/native/src/ThermionDartRenderThreadApi.cpp index ffaba43b..013af5ce 100644 --- a/thermion_dart/native/src/ThermionDartRenderThreadApi.cpp +++ b/thermion_dart/native/src/ThermionDartRenderThreadApi.cpp @@ -336,12 +336,13 @@ extern "C" bool keepData, int priority, int layer, + bool loadResourcesAsync, void (*callback)(EntityId)) { std::packaged_task lambda( [=]() mutable { - auto entity = SceneManager_loadGlbFromBuffer(sceneManager, data, length, keepData, priority, layer); + auto entity = SceneManager_loadGlbFromBuffer(sceneManager, data, length, keepData, priority, layer, loadResourcesAsync); callback(entity); return entity; });