diff --git a/thermion_dart/native/include/SceneManager.hpp b/thermion_dart/native/include/SceneManager.hpp index 9eea41e9..ae1eef93 100644 --- a/thermion_dart/native/include/SceneManager.hpp +++ b/thermion_dart/native/include/SceneManager.hpp @@ -287,6 +287,7 @@ 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 9c33462f..93314125 100644 --- a/thermion_dart/native/include/ThermionDartApi.h +++ b/thermion_dart/native/include/ThermionDartApi.h @@ -277,6 +277,7 @@ extern "C" 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); + EMSCRIPTEN_KEEPALIVE void set_material_depth_write(void *const sceneManager, EntityId entity, int materialIndex, bool enabled); EMSCRIPTEN_KEEPALIVE void unproject_texture(void *const sceneManager, EntityId entity,uint8_t* input, uint32_t inputWidth, uint32_t inputHeight, uint8_t *out, uint32_t outWidth, uint32_t outHeight); EMSCRIPTEN_KEEPALIVE void *const create_texture(void *const sceneManager, uint8_t *data, size_t length); EMSCRIPTEN_KEEPALIVE void destroy_texture(void *const sceneManager, void *const texture); diff --git a/thermion_dart/native/src/SceneManager.cpp b/thermion_dart/native/src/SceneManager.cpp index 109510b4..25c3b3d7 100644 --- a/thermion_dart/native/src/SceneManager.cpp +++ b/thermion_dart/native/src/SceneManager.cpp @@ -2610,6 +2610,20 @@ EntityId SceneManager::createGeometry( 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 2eb7cb25..fd7beb6a 100644 --- a/thermion_dart/native/src/ThermionDartApi.cpp +++ b/thermion_dart/native/src/ThermionDartApi.cpp @@ -978,6 +978,10 @@ 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); diff --git a/thermion_dart/test/integration_test.dart b/thermion_dart/test/integration_test.dart index 0feb5bef..e76a7bb3 100644 --- a/thermion_dart/test/integration_test.dart +++ b/thermion_dart/test/integration_test.dart @@ -547,6 +547,39 @@ 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 both materials, the red cube will render in front of the white cube + // (relying on insertion order) + await viewer.setMaterialDepthWrite(cube1, 0, false); + await viewer.setMaterialDepthWrite(cube2, 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", () {