From 5669ac5c55c021507b1c21ad37ed240c4fb8639c Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Tue, 10 Jun 2025 11:48:31 +0800 Subject: [PATCH] Dart wrappers for View/Scene are now stateful --- .../src/implementation/ffi_scene.dart | 67 ++++++++++++++----- .../filament/src/implementation/ffi_view.dart | 8 ++- 2 files changed, 56 insertions(+), 19 deletions(-) diff --git a/thermion_dart/lib/src/filament/src/implementation/ffi_scene.dart b/thermion_dart/lib/src/filament/src/implementation/ffi_scene.dart index 446f024c..4f4c0891 100644 --- a/thermion_dart/lib/src/filament/src/implementation/ffi_scene.dart +++ b/thermion_dart/lib/src/filament/src/implementation/ffi_scene.dart @@ -1,8 +1,12 @@ import 'package:thermion_dart/src/filament/src/implementation/ffi_asset.dart'; import 'package:thermion_dart/src/filament/src/interface/scene.dart'; import 'package:thermion_dart/thermion_dart.dart'; +import 'package:logging/logging.dart'; class FFIScene extends Scene { + + late final _logger = Logger(this.runtimeType.toString()); + final Pointer scene; FFIScene(this.scene); @@ -12,29 +16,48 @@ class FFIScene extends Scene { SceneAsset_addToScene(asset.asset, scene); } + /// + /// + /// @override Future addEntity(ThermionEntity entity) async { Scene_addEntity(scene, entity); } + /// + /// + /// @override Future remove(covariant FFIAsset asset) async { SceneAsset_removeFromScene(asset.asset, scene); } - final _outlines = {}; - /// /// /// @override Future removeStencilHighlight(ThermionAsset asset) async { - if (_outlines.containsKey(asset)) { - final highlight = _outlines[asset]!; - await remove(highlight); + if (!_highlighted.contains(asset)) { + _logger + .warning("No stencil highlight for asset (entity ${asset.entity})"); + return; } + _logger.info( + "Removing stencil highlight for asset (entity ${asset.entity})"); + _highlighted.remove(asset); + final highlight = _highlightInstances[asset]!; + + await remove(highlight); + await FilamentApp.instance!.destroyAsset(highlight); + + _logger.info( + "Removed stencil highlight for asset (entity ${asset.entity})"); } + static MaterialInstance? _highlightMaterialInstance; + final _highlightInstances = {}; + final _highlighted = {}; + /// /// /// @@ -47,7 +70,18 @@ class FFIScene extends Scene { int primitiveIndex = 0}) async { entity ??= asset.entity; - if (!_outlines.containsKey(asset)) { + if (_highlighted.contains(asset)) { + _logger + .info("Stencil highlight exists for asset (entity ${asset.entity})"); + } else { + + _highlighted.add(asset); + _highlightMaterialInstance ??= + await FilamentApp.instance!.createUnlitMaterialInstance(); + var highlightInstance = await asset + .createInstance(materialInstances: [_highlightMaterialInstance!]); + _highlightInstances[asset] = highlightInstance as FFIAsset; + var sourceMaterialInstance = await asset.getMaterialInstanceAt(entity: entity); await sourceMaterialInstance.setStencilWriteEnabled(true); @@ -60,21 +94,15 @@ class FFIScene extends Scene { await sourceMaterialInstance .setStencilReferenceValue(View.STENCIL_HIGHLIGHT_REFERENCE_VALUE); - var highlightMaterialInstance = - await FilamentApp.instance!.createUnlitMaterialInstance(); - - await highlightMaterialInstance + await _highlightMaterialInstance! .setStencilCompareFunction(SamplerCompareFunction.NE); - await highlightMaterialInstance + await _highlightMaterialInstance! .setStencilReferenceValue(View.STENCIL_HIGHLIGHT_REFERENCE_VALUE); - await highlightMaterialInstance.setDepthCullingEnabled(false); - await highlightMaterialInstance.setParameterFloat4( - "baseColorFactor", r, g, b, 1.0); + await _highlightMaterialInstance!.setDepthCullingEnabled(true); + await _highlightMaterialInstance! + .setParameterFloat4("baseColorFactor", r, g, b, 1.0); - var highlightInstance = await asset - .createInstance(materialInstances: [highlightMaterialInstance]); await add(highlightInstance as FFIAsset); - _outlines[asset] = highlightInstance as FFIAsset; var transform = await FilamentApp.instance! .getWorldTransform(highlightInstance.entity); @@ -85,6 +113,11 @@ class FFIScene extends Scene { await FilamentApp.instance!.setPriority(highlightInstance.entity, 7); await FilamentApp.instance!.setParent(highlightInstance.entity, entity); + + _logger + .info("Added stencil highlight for asset (entity ${asset.entity})"); } + + } } diff --git a/thermion_dart/lib/src/filament/src/implementation/ffi_view.dart b/thermion_dart/lib/src/filament/src/implementation/ffi_view.dart index 3655e01d..270a5e56 100644 --- a/thermion_dart/lib/src/filament/src/implementation/ffi_view.dart +++ b/thermion_dart/lib/src/filament/src/implementation/ffi_view.dart @@ -163,10 +163,14 @@ class FFIView extends View { View_setBlendMode(view, blendMode.index); } + FFIScene? _scene; + @override Future getScene() async { - final ptr = View_getScene(view); - return FFIScene(ptr); + if (_scene == null) { + _scene = FFIScene(View_getScene(view)); + } + return _scene!; } int _pickRequestId = -1;