From ecb8d8672adfc6e0f407463e11b88a503aa1e2a0 Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Fri, 28 Mar 2025 13:06:36 +0800 Subject: [PATCH] fix instancing so that gltf assets always fill the first instance slot --- .../viewer/src/ffi/src/ffi_filament_app.dart | 20 +++--- .../viewer/src/ffi/src/thermion_dart.g.dart | 65 ++++++------------ .../native/include/c_api/TGltfAssetLoader.h | 8 +++ .../native/include/c_api/TSceneAsset.h | 31 +-------- .../c_api/ThermionDartRenderThreadApi.h | 8 +-- .../native/include/scene/GltfSceneAsset.hpp | 17 +---- .../native/include/scene/SceneAsset.hpp | 1 - thermion_dart/native/src/c_api/TGizmo.cpp | 68 ++++++++++--------- .../native/src/c_api/TGltfAssetLoader.cpp | 14 ++++ .../native/src/c_api/TSceneAsset.cpp | 40 ++--------- .../src/c_api/ThermionDartRenderThreadApi.cpp | 33 +++++---- .../native/src/scene/GltfSceneAsset.cpp | 47 +++++++++++++ thermion_dart/test/instancing_tests.dart | 40 +++++++++++ 13 files changed, 206 insertions(+), 186 deletions(-) create mode 100644 thermion_dart/test/instancing_tests.dart 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 7b03bb7f..506ca6a0 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 @@ -749,16 +749,16 @@ class FFIFilamentApp extends FilamentApp { (cb) => GltfResourceLoader_createRenderThread(engine, relativeResourcePath?.toNativeUtf8().cast() ?? nullptr, cb)); - var asset = await withPointerCallback((cb) => - SceneAsset_loadGlbRenderThread(engine, gltfAssetLoader, - nameComponentManager, data.address, data.length, numInstances, cb)); + var filamentAsset = await withPointerCallback((cb) => + GltfAssetLoader_loadRenderThread(engine, gltfAssetLoader, data.address, + data.length, numInstances, cb)); - if (asset == nullptr) { + if (filamentAsset == nullptr) { throw Exception("An error occurred loading the asset"); } - var resourceUris = SceneAsset_getResourceUris(asset); - var resourceUriCount = SceneAsset_getResourceUriCount(asset); + var resourceUris = FilamentAsset_getResourceUris(filamentAsset); + var resourceUriCount = FilamentAsset_getResourceUriCount(filamentAsset); final resources = []; for (int i = 0; i < resourceUriCount; i++) { @@ -782,10 +782,6 @@ class FFIFilamentApp extends FilamentApp { throw UnimplementedError( "TODO"); // need to use a NativeFinalizer to ensure the pointer is still valid until resource loader has finished } else { - final filamentAsset = SceneAsset_getFilamentAsset(asset); - if (filamentAsset == nullptr) { - throw Exception(); - } final result = await withBoolCallback((cb) => GltfResourceLoader_loadResourcesRenderThread( gltfResourceLoader, filamentAsset, cb)); @@ -794,6 +790,10 @@ class FFIFilamentApp extends FilamentApp { } } + final asset = await withPointerCallback((cb) => + SceneAsset_createFromFilamentAssetRenderThread( + engine, gltfAssetLoader, nameComponentManager, filamentAsset, cb)); + await withVoidCallback((cb) => GltfResourceLoader_destroyRenderThread(engine, gltfResourceLoader, cb)); return FFIAsset(asset, this, animationManager.cast()); 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 79bf9ee8..f7218c21 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 @@ -473,6 +473,18 @@ external ffi.Pointer GltfAssetLoader_getMaterialProvider( ffi.Pointer tAssetLoader, ); +@ffi.Native)>(isLeaf: true) +external int FilamentAsset_getResourceUriCount( + ffi.Pointer tFilamentAsset, +); + +@ffi.Native< + ffi.Pointer> Function( + ffi.Pointer)>(isLeaf: true) +external ffi.Pointer> FilamentAsset_getResourceUris( + ffi.Pointer tFilamentAsset, +); + @ffi.Native)>(isLeaf: true) external TViewport View_getViewport( ffi.Pointer view, @@ -2111,22 +2123,18 @@ external void SceneAsset_destroyRenderThread( ffi.Pointer, ffi.Pointer, ffi.Pointer, - ffi.Pointer, - ffi.Size, - ffi.Size, + ffi.Pointer, ffi.Pointer< ffi .NativeFunction)>>)>( isLeaf: true) -external void SceneAsset_loadGlbRenderThread( +external void SceneAsset_createFromFilamentAssetRenderThread( ffi.Pointer tEngine, ffi.Pointer tAssetLoader, ffi.Pointer tNameComponentManager, - ffi.Pointer data, - int length, - int numInstances, + ffi.Pointer tFilamentAsset, ffi.Pointer)>> - callback, + onComplete, ); @ffi.Native< @@ -3234,47 +3242,12 @@ external ffi.Pointer SceneAsset_createGeometry( ffi.Pointer, ffi.Pointer, ffi.Pointer, - ffi.Pointer, - ffi.Size, - ffi.Size)>(isLeaf: true) -external ffi.Pointer SceneAsset_loadGlb( + ffi.Pointer)>(isLeaf: true) +external ffi.Pointer SceneAsset_createFromFilamentAsset( ffi.Pointer tEngine, ffi.Pointer tAssetLoader, ffi.Pointer tNameComponentManager, - ffi.Pointer data, - int length, - int numInstances, -); - -@ffi.Native< - ffi.Pointer Function( - ffi.Pointer, - ffi.Pointer, - ffi.Pointer, - ffi.Pointer, - ffi.Pointer, - ffi.Size, - ffi.Size)>(isLeaf: true) -external ffi.Pointer SceneAsset_loadGltf( - ffi.Pointer tAssetLoader, - ffi.Pointer tResourceLoader, - ffi.Pointer tEngine, - ffi.Pointer tNameComponentManager, - ffi.Pointer data, - int length, - int numInstances, -); - -@ffi.Native)>(isLeaf: true) -external int SceneAsset_getResourceUriCount( - ffi.Pointer tSceneAsset, -); - -@ffi.Native< - ffi.Pointer> Function( - ffi.Pointer)>(isLeaf: true) -external ffi.Pointer> SceneAsset_getResourceUris( - ffi.Pointer tSceneAsset, + ffi.Pointer tFilamentAsset, ); @ffi.Native Function(ffi.Pointer)>( diff --git a/thermion_dart/native/include/c_api/TGltfAssetLoader.h b/thermion_dart/native/include/c_api/TGltfAssetLoader.h index f2e645b9..d6a0cb83 100644 --- a/thermion_dart/native/include/c_api/TGltfAssetLoader.h +++ b/thermion_dart/native/include/c_api/TGltfAssetLoader.h @@ -20,6 +20,14 @@ EMSCRIPTEN_KEEPALIVE TFilamentAsset *GltfAssetLoader_load( EMSCRIPTEN_KEEPALIVE TMaterialInstance *GltfAssetLoader_getMaterialInstance(TRenderableManager *tRenderableManager, TFilamentAsset *tAsset); EMSCRIPTEN_KEEPALIVE TMaterialProvider *GltfAssetLoader_getMaterialProvider(TGltfAssetLoader *tAssetLoader); +EMSCRIPTEN_KEEPALIVE int32_t FilamentAsset_getResourceUriCount( + TFilamentAsset *tFilamentAsset +); + +EMSCRIPTEN_KEEPALIVE const char* const* FilamentAsset_getResourceUris( + TFilamentAsset *tFilamentAsset +); + #ifdef __cplusplus } #endif diff --git a/thermion_dart/native/include/c_api/TSceneAsset.h b/thermion_dart/native/include/c_api/TSceneAsset.h index c8aabb99..faca272d 100644 --- a/thermion_dart/native/include/c_api/TSceneAsset.h +++ b/thermion_dart/native/include/c_api/TSceneAsset.h @@ -22,38 +22,14 @@ extern "C" TMaterialInstance **materialInstances, int materialInstanceCount ); - - EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneAsset_loadGlb( + EMSCRIPTEN_KEEPALIVE TSceneAsset * SceneAsset_createFromFilamentAsset( TEngine *tEngine, TGltfAssetLoader *tAssetLoader, TNameComponentManager *tNameComponentManager, - const uint8_t *data, - size_t length, - size_t numInstances + TFilamentAsset *tFilamentAsset ); - - EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneAsset_loadGltf( - TGltfAssetLoader *tAssetLoader, - TGltfResourceLoader *tResourceLoader, - TEngine *tEngine, - TNameComponentManager *tNameComponentManager, - const uint8_t *data, - size_t length, - size_t numInstances - ); - - EMSCRIPTEN_KEEPALIVE int32_t SceneAsset_getResourceUriCount( - TSceneAsset *tSceneAsset - ); - - EMSCRIPTEN_KEEPALIVE const char* const* SceneAsset_getResourceUris( - TSceneAsset *tSceneAsset - ); - EMSCRIPTEN_KEEPALIVE TFilamentAsset *SceneAsset_getFilamentAsset(TSceneAsset *tSceneAsset); - EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneAsset_createGrid(TEngine *tEngine, TMaterial * tMaterial); - EMSCRIPTEN_KEEPALIVE void SceneAsset_destroy(TSceneAsset *tSceneAsset); EMSCRIPTEN_KEEPALIVE void SceneAsset_addToScene(TSceneAsset *tSceneAsset, TScene *tScene); EMSCRIPTEN_KEEPALIVE void SceneAsset_removeFromScene(TSceneAsset *tSceneAsset, TScene *tScene); @@ -68,8 +44,7 @@ extern "C" EMSCRIPTEN_KEEPALIVE size_t SceneAsset_getInstanceCount(TSceneAsset *tSceneAsset); EMSCRIPTEN_KEEPALIVE TSceneAsset * SceneAsset_createInstance(TSceneAsset *asset, TMaterialInstance **materialInstances, int materialInstanceCount); EMSCRIPTEN_KEEPALIVE Aabb3 SceneAsset_getBoundingBox(TSceneAsset *asset); - EMSCRIPTEN_KEEPALIVE Aabb3 SceneAsset_getBoundingBox(TSceneAsset *asset); - + #ifdef __cplusplus } #endif diff --git a/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h b/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h index bd2c0500..938e1a2d 100644 --- a/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h +++ b/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h @@ -92,14 +92,12 @@ namespace thermion FilamentRenderCallback make_render_callback_fn_pointer(FilamentRenderCallback); EMSCRIPTEN_KEEPALIVE void SceneAsset_destroyRenderThread(TSceneAsset *tSceneAsset, void (*onComplete)()); - EMSCRIPTEN_KEEPALIVE void SceneAsset_loadGlbRenderThread( + EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread( TEngine *tEngine, TGltfAssetLoader *tAssetLoader, TNameComponentManager *tNameComponentManager, - uint8_t *data, - size_t length, - size_t numInstances, - void (*callback)(TSceneAsset *) + TFilamentAsset *tFilamentAsset, + void (*onComplete)(TSceneAsset *) ); EMSCRIPTEN_KEEPALIVE void SceneAsset_createInstanceRenderThread(TSceneAsset *asset, TMaterialInstance **tMaterialInstances, int materialInstanceCount, void (*callback)(TSceneAsset *)); EMSCRIPTEN_KEEPALIVE void SceneAsset_createGeometryRenderThread( diff --git a/thermion_dart/native/include/scene/GltfSceneAsset.hpp b/thermion_dart/native/include/scene/GltfSceneAsset.hpp index cb8943e5..debae4b1 100644 --- a/thermion_dart/native/include/scene/GltfSceneAsset.hpp +++ b/thermion_dart/native/include/scene/GltfSceneAsset.hpp @@ -27,6 +27,7 @@ namespace thermion class GltfSceneAsset : public SceneAsset { public: + GltfSceneAsset( gltfio::FilamentAsset *asset, gltfio::AssetLoader *assetLoader, @@ -34,25 +35,13 @@ namespace thermion utils::NameComponentManager* ncm, MaterialInstance **materialInstances = nullptr, size_t materialInstanceCount = 0, - int instanceIndex = -1) : _asset(asset), - _assetLoader(assetLoader), - _engine(engine), - _ncm(ncm), - _materialInstances(materialInstances), - _materialInstanceCount(materialInstanceCount) - { - TRACE("Created GltfSceneAsset from FilamentAsset %d with %d reserved instances", asset, asset->getAssetInstanceCount()); - } + int instanceIndex = 0); ~GltfSceneAsset(); SceneAsset *createInstance(MaterialInstance **materialInstances = nullptr, size_t materialInstanceCount = 0) override; - void destroyInstance(SceneAsset *asset) override { - auto it = std::remove_if(_instances.begin(), _instances.end(), [=](auto &sceneAsset) - { return sceneAsset.get() == asset; }); - _instances.erase(it, _instances.end()); - }; + void destroyInstance(SceneAsset *asset) override; SceneAssetType getType() override { diff --git a/thermion_dart/native/include/scene/SceneAsset.hpp b/thermion_dart/native/include/scene/SceneAsset.hpp index ff68ad77..5e8337f8 100644 --- a/thermion_dart/native/include/scene/SceneAsset.hpp +++ b/thermion_dart/native/include/scene/SceneAsset.hpp @@ -3,7 +3,6 @@ #include #include - #include #include #include diff --git a/thermion_dart/native/src/c_api/TGizmo.cpp b/thermion_dart/native/src/c_api/TGizmo.cpp index 951069ce..4f075480 100644 --- a/thermion_dart/native/src/c_api/TGizmo.cpp +++ b/thermion_dart/native/src/c_api/TGizmo.cpp @@ -4,6 +4,7 @@ #include "c_api/TGizmo.h" #include "c_api/TSceneAsset.h" +#include "c_api/TGltfAssetLoader.h" #include "scene/Gizmo.hpp" #include "scene/GltfSceneAsset.hpp" #include "resources/translation_gizmo_glb.h" @@ -20,56 +21,59 @@ namespace thermion EMSCRIPTEN_KEEPALIVE TGizmo *Gizmo_create( TEngine *tEngine, - TGltfAssetLoader *assetLoader, + TGltfAssetLoader *tAssetLoader, TGltfResourceLoader *tGltfResourceLoader, TNameComponentManager *tNameComponentManager, TView *tView, TMaterial *tMaterial, - TGizmoType tGizmoType) { + TGizmoType tGizmoType) + { auto *engine = reinterpret_cast(tEngine); auto *view = reinterpret_cast(tView); auto *material = reinterpret_cast(tMaterial); auto *gltfResourceLoader = reinterpret_cast(tGltfResourceLoader); - TSceneAsset *sceneAsset; + const uint8_t *data; + size_t size; switch (tGizmoType) { case GIZMO_TYPE_TRANSLATION: - { + { TRACE("Building translation gizmo"); - sceneAsset = SceneAsset_loadGlb( - tEngine, - assetLoader, - tNameComponentManager, - TRANSLATION_GIZMO_GLB_TRANSLATION_GIZMO_DATA, - TRANSLATION_GIZMO_GLB_TRANSLATION_GIZMO_SIZE, - 3 - ); + data = TRANSLATION_GIZMO_GLB_TRANSLATION_GIZMO_DATA; + size = TRANSLATION_GIZMO_GLB_TRANSLATION_GIZMO_SIZE; break; - } - case GIZMO_TYPE_ROTATION: - { - TRACE("Building rotation gizmo"); - sceneAsset = SceneAsset_loadGlb( - tEngine, - assetLoader, - tNameComponentManager, - ROTATION_GIZMO_GLB_ROTATION_GIZMO_DATA, - ROTATION_GIZMO_GLB_ROTATION_GIZMO_SIZE, - 3 - ); - break; - } } + case GIZMO_TYPE_ROTATION: + { + TRACE("Building rotation gizmo"); + data = ROTATION_GIZMO_GLB_ROTATION_GIZMO_DATA; + size = ROTATION_GIZMO_GLB_ROTATION_GIZMO_SIZE; + break; + } + } + + auto *tFilamentAsset = GltfAssetLoader_load( + tEngine, + tAssetLoader, + data, + size, + 3); + auto *filamentAsset = reinterpret_cast(tFilamentAsset); + auto *sceneAsset = SceneAsset_createFromFilamentAsset( + tEngine, + tAssetLoader, + tNameComponentManager, + tFilamentAsset); + auto *gltfSceneAsset = reinterpret_cast(sceneAsset); - auto *filamentAsset = gltfSceneAsset->getAsset(); + gltfResourceLoader->loadResources(filamentAsset); auto *gizmo = new Gizmo( - gltfSceneAsset, - engine, - view, - material - ); + gltfSceneAsset, + engine, + view, + material); return reinterpret_cast(gizmo); } diff --git a/thermion_dart/native/src/c_api/TGltfAssetLoader.cpp b/thermion_dart/native/src/c_api/TGltfAssetLoader.cpp index 8a455c62..f24cca71 100644 --- a/thermion_dart/native/src/c_api/TGltfAssetLoader.cpp +++ b/thermion_dart/native/src/c_api/TGltfAssetLoader.cpp @@ -114,6 +114,20 @@ EMSCRIPTEN_KEEPALIVE TMaterialProvider *GltfAssetLoader_getMaterialProvider(TGlt return reinterpret_cast(&materialProvider); } +EMSCRIPTEN_KEEPALIVE int32_t FilamentAsset_getResourceUriCount( + TFilamentAsset *tFilamentAsset +) { + auto *filamentAsset = reinterpret_cast(tFilamentAsset); + return filamentAsset->getResourceUriCount(); +} + +EMSCRIPTEN_KEEPALIVE const char* const* FilamentAsset_getResourceUris( + TFilamentAsset *tFilamentAsset +) { + auto *filamentAsset = reinterpret_cast(tFilamentAsset); + return filamentAsset->getResourceUris(); +} + #ifdef __cplusplus } } diff --git a/thermion_dart/native/src/c_api/TSceneAsset.cpp b/thermion_dart/native/src/c_api/TSceneAsset.cpp index b2e09d14..f3396c52 100644 --- a/thermion_dart/native/src/c_api/TSceneAsset.cpp +++ b/thermion_dart/native/src/c_api/TSceneAsset.cpp @@ -66,17 +66,14 @@ extern "C" } - EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneAsset_loadGlb( + EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneAsset_createFromFilamentAsset( TEngine *tEngine, TGltfAssetLoader *tAssetLoader, TNameComponentManager *tNameComponentManager, - const uint8_t *data, - size_t length, - size_t numInstances + TFilamentAsset *tFilamentAsset ) { auto *engine = reinterpret_cast(tEngine); auto *nameComponentManager = reinterpret_cast(tNameComponentManager); - auto *tFilamentAsset = GltfAssetLoader_load(tEngine, tAssetLoader, data, length, numInstances); auto *filamentAsset = reinterpret_cast(tFilamentAsset); auto *assetLoader = reinterpret_cast(tAssetLoader); @@ -89,33 +86,6 @@ extern "C" return reinterpret_cast(sceneAsset); } - - - EMSCRIPTEN_KEEPALIVE int32_t SceneAsset_getResourceUriCount( - TSceneAsset *tSceneAsset - ) { - auto sceneAsset = reinterpret_cast(tSceneAsset); - if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf) { - Log("Error - not a gltf asset"); - return -1; - } - auto gltfAsset = reinterpret_cast(tSceneAsset); - auto *filamentAsset = gltfAsset->getAsset(); - return filamentAsset->getResourceUriCount(); - } - - EMSCRIPTEN_KEEPALIVE const char* const* SceneAsset_getResourceUris( - TSceneAsset *tSceneAsset - ) { - auto sceneAsset = reinterpret_cast(tSceneAsset); - if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf) { - Log("Error - not a gltf asset"); - return nullptr; - } - auto gltfAsset = reinterpret_cast(tSceneAsset); - auto *filamentAsset = gltfAsset->getAsset(); - return filamentAsset->getResourceUris(); - } EMSCRIPTEN_KEEPALIVE TFilamentAsset *SceneAsset_getFilamentAsset(TSceneAsset *tSceneAsset) { auto sceneAsset = reinterpret_cast(tSceneAsset); @@ -130,7 +100,6 @@ extern "C" return reinterpret_cast(filamentAsset); } - EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneAsset_createGrid(TEngine *tEngine, TMaterial* tMaterial) { auto *engine = reinterpret_cast(tEngine); auto *material = reinterpret_cast(tMaterial); @@ -234,6 +203,11 @@ extern "C" return reinterpret_cast(instance); } + EMSCRIPTEN_KEEPALIVE size_t SceneAsset_getInstanceCount(TSceneAsset *tSceneAsset) { + auto *asset = reinterpret_cast(tSceneAsset); + return asset->getInstanceCount(); + } + EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneAsset_createInstance(TSceneAsset *tSceneAsset, TMaterialInstance **tMaterialInstances, int materialInstanceCount) { auto *materialInstances = reinterpret_cast(tMaterialInstances); diff --git a/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp b/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp index d02ccdf6..455365e9 100644 --- a/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp +++ b/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp @@ -415,23 +415,6 @@ extern "C" auto fut = _renderThread->add_task(lambda); } - EMSCRIPTEN_KEEPALIVE void SceneAsset_loadGlbRenderThread( - TEngine *tEngine, - TGltfAssetLoader *tAssetLoader, - TNameComponentManager *tNameComponentManager, - uint8_t *data, - size_t length, - size_t numInstances, - void (*callback)(TSceneAsset *) - ) { - std::packaged_task lambda( - [=] - { - auto sceneAsset = SceneAsset_loadGlb(tEngine, tAssetLoader, tNameComponentManager, data, length, numInstances); - callback(sceneAsset); - }); - auto fut = _renderThread->add_task(lambda); - } EMSCRIPTEN_KEEPALIVE void SceneAsset_createGeometryRenderThread( TEngine *tEngine, @@ -457,6 +440,22 @@ extern "C" auto fut = _renderThread->add_task(lambda); } +EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread( + TEngine *tEngine, + TGltfAssetLoader *tAssetLoader, + TNameComponentManager *tNameComponentManager, + TFilamentAsset *tFilamentAsset, + void (*onComplete)(TSceneAsset *) +) { + std::packaged_task lambda( + [=] + { + auto sceneAsset = SceneAsset_createFromFilamentAsset(tEngine, tAssetLoader, tNameComponentManager, tFilamentAsset); + onComplete(sceneAsset); + }); + auto fut = _renderThread->add_task(lambda); +} + EMSCRIPTEN_KEEPALIVE void SceneAsset_createInstanceRenderThread( TSceneAsset *asset, TMaterialInstance **tMaterialInstances, int materialInstanceCount, diff --git a/thermion_dart/native/src/scene/GltfSceneAsset.cpp b/thermion_dart/native/src/scene/GltfSceneAsset.cpp index d78b360a..be20c778 100644 --- a/thermion_dart/native/src/scene/GltfSceneAsset.cpp +++ b/thermion_dart/native/src/scene/GltfSceneAsset.cpp @@ -3,9 +3,49 @@ #include "scene/GltfSceneAssetInstance.hpp" #include "gltfio/FilamentInstance.h" #include "Log.hpp" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "scene/GltfSceneAssetInstance.hpp" +#include "components/AnimationComponentManager.hpp" +#include "components/CollisionComponentManager.hpp" + +#include "scene/SceneAsset.hpp" + + + namespace thermion { + GltfSceneAsset::GltfSceneAsset( + gltfio::FilamentAsset *asset, + gltfio::AssetLoader *assetLoader, + Engine *engine, + utils::NameComponentManager* ncm, + MaterialInstance **materialInstances, + size_t materialInstanceCount, + int instanceIndex) : _asset(asset), + _assetLoader(assetLoader), + _engine(engine), + _ncm(ncm), + _materialInstances(materialInstances), + _materialInstanceCount(materialInstanceCount) + { + createInstance(); + TRACE("Created GltfSceneAsset from FilamentAsset %d with %d reserved instances", asset, asset->getAssetInstanceCount()); + } + GltfSceneAsset::~GltfSceneAsset() { _instances.clear(); @@ -14,6 +54,13 @@ namespace thermion TRACE("Destroyed"); } + void GltfSceneAsset::destroyInstance(SceneAsset *asset) { + auto it = std::remove_if(_instances.begin(), _instances.end(), [=](auto &sceneAsset) + { return sceneAsset.get() == asset; }); + _instances.erase(it, _instances.end()); + }; + + SceneAsset *GltfSceneAsset::createInstance(MaterialInstance **materialInstances, size_t materialInstanceCount) { auto instanceNumber = _instances.size(); diff --git a/thermion_dart/test/instancing_tests.dart b/thermion_dart/test/instancing_tests.dart new file mode 100644 index 00000000..68ed39b4 --- /dev/null +++ b/thermion_dart/test/instancing_tests.dart @@ -0,0 +1,40 @@ +@Timeout(const Duration(seconds: 600)) +import 'package:test/test.dart'; +import 'package:vector_math/vector_math_64.dart'; +import 'helpers.dart'; + +void main() async { + final testHelper = TestHelper("instancing"); + await testHelper.setup(); + test('gltf assets always create one instance', () async { + await testHelper.withViewer((viewer) async { + var asset = + await viewer.loadGltf("file://${testHelper.testDir}/assets/cube.glb"); + expect(await asset.getInstanceCount(), 1); + }); + }); + + test('create gltf instance', () async { + await testHelper.withViewer((viewer) async { + await viewer + .loadIbl("file://${testHelper.testDir}/assets/default_env_ibl.ktx"); + await viewer.loadSkybox( + "file://${testHelper.testDir}/assets/default_env_skybox.ktx"); + await viewer.setPostProcessing(true); + await viewer.setAntiAliasing(false, true, false); + + var asset = await viewer.loadGltf( + "file://${testHelper.testDir}/assets/cube.glb", + numInstances: 2); + + await testHelper.capture(viewer.view, "gltf"); + var instance = await asset.createInstance(); + await viewer.addToScene(instance); + print(instance.entity); + print(await instance.getChildEntities()); + + await instance.setTransform(Matrix4.translation(Vector3(1, 0, 0))); + await testHelper.capture(viewer.view, "gltf_with_instance"); + }); + }); +}