From 7cb308059643d35be95fcec73618e067bf869f95 Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Fri, 20 Sep 2024 18:18:08 +0800 Subject: [PATCH] move MaterialInstance methods to own class --- .../viewer/ffi/thermion_dart.g.dart | 32 ++++++--- .../viewer/ffi/thermion_viewer_ffi.dart | 31 ++++++--- .../viewer/shared_types/material.dart | 9 +-- .../viewer/thermion_viewer_base.dart | 15 ++--- .../viewer/thermion_viewer_stub.dart | 24 +++++++ .../viewer/web/thermion_viewer_wasm.dart | 2 +- thermion_dart/native/include/SceneManager.hpp | 1 - .../native/include/ThermionDartApi.h | 7 +- thermion_dart/native/src/SceneManager.cpp | 16 +---- thermion_dart/native/src/ThermionDartApi.cpp | 11 ++-- thermion_dart/test/integration_test.dart | 66 ++++++++++--------- 11 files changed, 128 insertions(+), 86 deletions(-) diff --git a/thermion_dart/lib/thermion_dart/viewer/ffi/thermion_dart.g.dart b/thermion_dart/lib/thermion_dart/viewer/ffi/thermion_dart.g.dart index e87ac730..faee88ce 100644 --- a/thermion_dart/lib/thermion_dart/viewer/ffi/thermion_dart.g.dart +++ b/thermion_dart/lib/thermion_dart/viewer/ffi/thermion_dart.g.dart @@ -1211,15 +1211,6 @@ external void remove_stencil_highlight( int entity, ); -@ffi.Native< - ffi.Pointer Function( - ffi.Pointer, EntityId, ffi.Int)>(isLeaf: true) -external ffi.Pointer get_material_instance_at( - ffi.Pointer sceneManager, - int entity, - int materialIndex, -); - @ffi.Native< ffi.Void Function(ffi.Pointer, EntityId, ffi.Int, ffi.Pointer, ffi.Float)>(isLeaf: true) @@ -1311,6 +1302,29 @@ external void apply_texture_to_material( int materialIndex, ); +@ffi.Native< + ffi.Pointer Function( + ffi.Pointer, EntityId, ffi.Int)>(isLeaf: true) +external ffi.Pointer get_material_instance_at( + ffi.Pointer sceneManager, + int entity, + int materialIndex, +); + +@ffi.Native, ffi.Bool)>( + isLeaf: true) +external void MaterialInstance_setDepthWrite( + ffi.Pointer materialInstance, + bool enabled, +); + +@ffi.Native, ffi.Bool)>( + isLeaf: true) +external void MaterialInstance_setDepthCulling( + ffi.Pointer materialInstance, + bool enabled, +); + @ffi.Native< ffi.Void Function( ffi.Pointer, diff --git a/thermion_dart/lib/thermion_dart/viewer/ffi/thermion_viewer_ffi.dart b/thermion_dart/lib/thermion_dart/viewer/ffi/thermion_viewer_ffi.dart index f015ecad..e82a6a8c 100644 --- a/thermion_dart/lib/thermion_dart/viewer/ffi/thermion_viewer_ffi.dart +++ b/thermion_dart/lib/thermion_dart/viewer/ffi/thermion_viewer_ffi.dart @@ -1982,15 +1982,6 @@ class ThermionViewerFFI extends ThermionViewer { allocator.free(ptr); } - /// - /// - /// - Future setMaterialDepthWrite( - ThermionEntity entity, int materialIndex, bool enabled) { - set_material_depth_write(_sceneManager!, entity, materialIndex, enabled); - return Future.value(); - } - Future unproject(ThermionEntity entity, Uint8List input, int inputWidth, int inputHeight, int outWidth, int outHeight) async { final outPtr = Uint8List(outWidth * outHeight * 4); @@ -2132,6 +2123,18 @@ class ThermionViewerFFI extends ThermionViewer { allocator.free(ptr); return Future.value(); } + + /// + /// + /// + Future getMaterialInstanceAt( + ThermionEntity entity, int index) async { + final instance = get_material_instance_at(_sceneManager!, entity, index); + if (instance == nullptr) { + return null; + } + return ThermionFFIMaterialInstance(instance); + } } class ThermionFFITexture extends ThermionTexture { @@ -2144,4 +2147,14 @@ class ThermionFFIMaterialInstance extends MaterialInstance { final Pointer _pointer; ThermionFFIMaterialInstance(this._pointer); + + @override + Future setDepthCullingEnabled(bool enabled) async { + MaterialInstance_setDepthCulling(this._pointer, enabled); + } + + @override + Future setDepthWriteEnabled(bool enabled) async { + MaterialInstance_setDepthWrite(this._pointer, enabled); + } } diff --git a/thermion_dart/lib/thermion_dart/viewer/shared_types/material.dart b/thermion_dart/lib/thermion_dart/viewer/shared_types/material.dart index fad70382..8fad022a 100644 --- a/thermion_dart/lib/thermion_dart/viewer/shared_types/material.dart +++ b/thermion_dart/lib/thermion_dart/viewer/shared_types/material.dart @@ -1,9 +1,6 @@ abstract class MaterialInstance { - + Future setDepthWriteEnabled(bool enabled); + Future setDepthCullingEnabled(bool enabled); } -enum AlphaMode { - OPAQUE, - MASK, - BLEND -} \ No newline at end of file +enum AlphaMode { OPAQUE, MASK, BLEND } diff --git a/thermion_dart/lib/thermion_dart/viewer/thermion_viewer_base.dart b/thermion_dart/lib/thermion_dart/viewer/thermion_viewer_base.dart index f0081542..a67dee2c 100644 --- a/thermion_dart/lib/thermion_dart/viewer/thermion_viewer_base.dart +++ b/thermion_dart/lib/thermion_dart/viewer/thermion_viewer_base.dart @@ -599,13 +599,6 @@ abstract class ThermionViewer { Future setMaterialPropertyInt( ThermionEntity entity, String propertyName, int materialIndex, int value); - /// - /// Sets the depthWrite material instance at [materialIndex] for [entity] to [enabled]. - /// [entity] must have a Renderable attached. - /// - Future setMaterialDepthWrite( - ThermionEntity entity, int materialIndex, bool enabled); - /// /// Scale [entity] to fit within the unit cube. /// @@ -858,7 +851,7 @@ abstract class ThermionViewer { /// /// Assigns [entity] to visibility layer [layer]. - /// + /// Future setVisibilityLayer(ThermionEntity entity, int layer); /// @@ -944,4 +937,10 @@ abstract class ThermionViewer { /// /// Future createUnlitMaterialInstance(); + + /// + /// + /// + Future getMaterialInstanceAt( + ThermionEntity entity, int index); } diff --git a/thermion_dart/lib/thermion_dart/viewer/thermion_viewer_stub.dart b/thermion_dart/lib/thermion_dart/viewer/thermion_viewer_stub.dart index b9465660..7d32a6af 100644 --- a/thermion_dart/lib/thermion_dart/viewer/thermion_viewer_stub.dart +++ b/thermion_dart/lib/thermion_dart/viewer/thermion_viewer_stub.dart @@ -928,6 +928,30 @@ class ThermionViewerStub extends ThermionViewer { // TODO: implement setMaterialPropertyInt throw UnimplementedError(); } + + @override + Future getMaterialInstanceAt(ThermionEntity entity, int index) { + // TODO: implement getMaterialInstanceAt + throw UnimplementedError(); + } + + @override + Future setLayerVisibility(int layer, bool visible) { + // TODO: implement setLayerVisibility + throw UnimplementedError(); + } + + @override + Future setMaterialDepthWrite(ThermionEntity entity, int materialIndex, bool enabled) { + // TODO: implement setMaterialDepthWrite + throw UnimplementedError(); + } + + @override + Future setVisibilityLayer(ThermionEntity entity, int layer) { + // TODO: implement setVisibilityLayer + throw UnimplementedError(); + } } diff --git a/thermion_dart/lib/thermion_dart/viewer/web/thermion_viewer_wasm.dart b/thermion_dart/lib/thermion_dart/viewer/web/thermion_viewer_wasm.dart index 0ebb0399..8b42765d 100644 --- a/thermion_dart/lib/thermion_dart/viewer/web/thermion_viewer_wasm.dart +++ b/thermion_dart/lib/thermion_dart/viewer/web/thermion_viewer_wasm.dart @@ -2186,7 +2186,7 @@ class ThermionViewerWasm implements ThermionViewer { @override Future setLayerEnabled(int layer, bool enabled) async { _module!.ccall( - "set_layer_enabled", + "set_layer_visibility", "void", [ "void*".toJS, diff --git a/thermion_dart/native/include/SceneManager.hpp b/thermion_dart/native/include/SceneManager.hpp index 95052bfe..c5b58b93 100644 --- a/thermion_dart/native/include/SceneManager.hpp +++ b/thermion_dart/native/include/SceneManager.hpp @@ -287,7 +287,6 @@ namespace thermion_filament void setMaterialProperty(EntityId entity, int materialIndex, const char* property, float value); void setMaterialProperty(EntityId entity, int materialIndex, const char* property, int32_t value); void setMaterialProperty(EntityId entityId, int materialIndex, const char* property, filament::math::float4& value); - void setMaterialDepthWrite(EntityId entityId, int materialIndex, bool enabled); MaterialInstance* createUbershaderMaterialInstance(MaterialKey key); void destroy(MaterialInstance* materialInstance); diff --git a/thermion_dart/native/include/ThermionDartApi.h b/thermion_dart/native/include/ThermionDartApi.h index 7d98deaf..38ea24f4 100644 --- a/thermion_dart/native/include/ThermionDartApi.h +++ b/thermion_dart/native/include/ThermionDartApi.h @@ -275,7 +275,6 @@ extern "C" EMSCRIPTEN_KEEPALIVE void set_gizmo_visibility(void *const sceneManager, bool visible); EMSCRIPTEN_KEEPALIVE void set_stencil_highlight(void *const sceneManager, EntityId entity, float r, float g, float b); EMSCRIPTEN_KEEPALIVE void remove_stencil_highlight(void *const sceneManager, EntityId entity); - EMSCRIPTEN_KEEPALIVE TMaterialInstance* get_material_instance_at(void *const sceneManager, EntityId entity, int materialIndex); EMSCRIPTEN_KEEPALIVE void set_material_property_float(void *const sceneManager, EntityId entity, int materialIndex, const char *property, float value); EMSCRIPTEN_KEEPALIVE void set_material_property_int(void *const sceneManager, EntityId entity, int materialIndex, const char *property, int value); EMSCRIPTEN_KEEPALIVE void set_material_property_float4(void *const sceneManager, EntityId entity, int materialIndex, const char *property, double4 value); @@ -285,6 +284,12 @@ extern "C" EMSCRIPTEN_KEEPALIVE void destroy_texture(void *const sceneManager, void *const texture); EMSCRIPTEN_KEEPALIVE void apply_texture_to_material(void *const sceneManager, EntityId entity, void *const texture, const char *parameterName, int materialIndex); + EMSCRIPTEN_KEEPALIVE TMaterialInstance* get_material_instance_at(void *const sceneManager, EntityId entity, int materialIndex); + + EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthWrite(TMaterialInstance* materialInstance, bool enabled); + EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthCulling(TMaterialInstance* materialInstance, bool enabled); + + #ifdef __cplusplus } #endif diff --git a/thermion_dart/native/src/SceneManager.cpp b/thermion_dart/native/src/SceneManager.cpp index b1134a50..1b659679 100644 --- a/thermion_dart/native/src/SceneManager.cpp +++ b/thermion_dart/native/src/SceneManager.cpp @@ -2633,20 +2633,6 @@ EntityId SceneManager::createGeometry( auto instance = _unlitMaterialProvider->createMaterialInstance(nullptr, &uvmap); return instance; } - - void SceneManager::setMaterialDepthWrite(EntityId entityId, int materialIndex, bool enabled) { - auto entity = Entity::import(entityId); - const auto &rm = _engine->getRenderableManager(); - auto renderableInstance = rm.getInstance(entity); - if (!renderableInstance.isValid()) - { - Log("Error setting material property for entity %d: no renderable"); - return; - } - auto materialInstance = rm.getMaterialInstanceAt(renderableInstance, materialIndex); - materialInstance->setDepthWrite(enabled); - } - - + } // namespace thermion_filament diff --git a/thermion_dart/native/src/ThermionDartApi.cpp b/thermion_dart/native/src/ThermionDartApi.cpp index 1022102a..b3b96b8b 100644 --- a/thermion_dart/native/src/ThermionDartApi.cpp +++ b/thermion_dart/native/src/ThermionDartApi.cpp @@ -987,10 +987,6 @@ extern "C" ((SceneManager *)sceneManager)->setMaterialProperty(entity, materialIndex, property, filamentValue); } - EMSCRIPTEN_KEEPALIVE void set_material_depth_write(void *const sceneManager, EntityId entity, int materialIndex, bool enabled) { - ((SceneManager *)sceneManager)->setMaterialDepthWrite(entity, materialIndex, enabled); - } - EMSCRIPTEN_KEEPALIVE void unproject_texture(void *const viewer, EntityId entity, uint8_t* input, uint32_t inputWidth, uint32_t inputHeight, uint8_t *out, uint32_t outWidth, uint32_t outHeight) { ((FilamentViewer *)viewer)->unprojectTexture(entity, input, inputWidth, inputHeight, out, outWidth, outHeight); @@ -1054,4 +1050,11 @@ EMSCRIPTEN_KEEPALIVE TMaterialInstance *create_unlit_material_instance(void *con EMSCRIPTEN_KEEPALIVE void destroy_material_instance(void *const sceneManager, TMaterialInstance *instance) { ((SceneManager *)sceneManager)->destroy(reinterpret_cast(instance)); } + +EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthWrite(TMaterialInstance* materialInstance, bool enabled) { + reinterpret_cast(materialInstance)->setDepthWrite(enabled); +} +EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthCulling(TMaterialInstance* materialInstance, bool enabled) { + reinterpret_cast(materialInstance)->setDepthCulling(enabled); +} } diff --git a/thermion_dart/test/integration_test.dart b/thermion_dart/test/integration_test.dart index 891986e5..22d130ef 100644 --- a/thermion_dart/test/integration_test.dart +++ b/thermion_dart/test/integration_test.dart @@ -440,6 +440,40 @@ void main() async { }); }); + group("MaterialInstance", () { + test('disable depth write', () async { + var viewer = await createViewer(); + await viewer.setBackgroundColor(1.0, 0.0, 0.0, 1.0); + await viewer.setCameraPosition(0, 0, 6); + await viewer.addDirectLight( + DirectLight.sun(direction: Vector3(0, 0, -1)..normalize())); + + final cube1 = await viewer.createGeometry(GeometryHelper.cube()); + var materialInstance = await viewer.getMaterialInstanceAt(cube1, 0); + + final cube2 = await viewer.createGeometry(GeometryHelper.cube()); + await viewer.setMaterialPropertyFloat4( + cube2, "baseColorFactor", 0, 0, 1, 0, 1); + await viewer.setPosition(cube2, 1.0, 0.0, -1.0); + + expect(materialInstance, isNotNull); + + // with depth write enabled on both materials, cube2 renders behind the white cube + await _capture(viewer, "material_instance_depth_write_enabled"); + + // if we disable depth write on cube1, then cube2 will always appear in front + // (relying on insertion order) + materialInstance!.setDepthWriteEnabled(false); + await _capture(viewer, "material_instance_depth_write_disabled"); + + // set priority for the cube1 cube to 7 (render) last, cube1 renders in front + await viewer.setPriority(cube1, 7); + await _capture(viewer, "material_instance_depth_write_disabled_with_priority"); + }); + }); + + + // test('create instance from glb when keepData is true', () async { // var model = await viewer.loadGlb("$testDir/cube.glb", keepData: true); // await viewer.transformToUnitCube(model); @@ -547,38 +581,6 @@ void main() async { await viewer.setMaterialPropertyFloat(cube, "roughnessFactor", 0, 0.0); await _capture(viewer, "set_material_roughness_post"); }); - - test('enable/disable depth write for custom geometry', () async { - var viewer = await createViewer(); - - await viewer.setCameraPosition(0, 0, 6); - await viewer.setBackgroundColor(0.0, 0.0, 1.0, 1.0); - var light = - await viewer.addLight(LightType.SUN, 6500, 100000, 0, 0, 0, 0, 0, -1); - - final cube1 = await viewer.createGeometry(GeometryHelper.cube()); - await viewer.setMaterialPropertyFloat4( - cube1, "baseColorFactor", 0, 1.0, 1.0, 1.0, 1); - final cube2 = await viewer.createGeometry(GeometryHelper.cube()); - await viewer.setPosition(cube2, 1.0, 0.0, -1.0); - await viewer.setMaterialPropertyFloat4( - cube2, "baseColorFactor", 0, 1.0, 0, 0, 1); - - // with depth write enabled on both materials, the red cube will render behind the white cube - await viewer.setMaterialDepthWrite(cube1, 0, true); - await viewer.setMaterialDepthWrite(cube2, 0, true); - await _capture(viewer, "geometry_enable_depth_write"); - - // with depth write disabled on the first material, the red cube will render in front of the white cube - // (relying on insertion order) - await viewer.setMaterialDepthWrite(cube1, 0, false); - - await _capture(viewer, "geometry_disable_depth_write_insertion_order"); - - // if we set priority for the black cube to 7 (render) last, red cube will render behind the white cube - await viewer.setPriority(cube1, 7); - await _capture(viewer, "geometry_disable_depth_write_priority"); - }); }); group("transforms & parenting", () {