internal: remove bounding box asset when parent asset removed

This commit is contained in:
Nick Fisher
2025-01-02 10:30:13 +08:00
parent 31e453a4e6
commit 7717387909
3 changed files with 45 additions and 17 deletions

View File

@@ -6,6 +6,7 @@ import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_viewer_ffi.dart';
import 'package:thermion_dart/thermion_dart.dart'; import 'package:thermion_dart/thermion_dart.dart';
class FFIAsset extends ThermionAsset { class FFIAsset extends ThermionAsset {
final Pointer<TSceneAsset> pointer; final Pointer<TSceneAsset> pointer;
final Pointer<TSceneManager> sceneManager; final Pointer<TSceneManager> sceneManager;
Pointer<TRenderableManager> get renderableManager => Pointer<TRenderableManager> get renderableManager =>
@@ -188,7 +189,7 @@ class FFIAsset extends ThermionAsset {
} }
} }
ThermionAsset? _boundingBoxAsset; FFIAsset? boundingBoxAsset;
Future<Aabb3> getBoundingBox() async { Future<Aabb3> getBoundingBox() async {
late ThermionEntity targetEntity; late ThermionEntity targetEntity;
@@ -201,9 +202,10 @@ class FFIAsset extends ThermionAsset {
return aabb3; return aabb3;
} }
@override @override
Future<void> setBoundingBoxVisibility(bool visible) async { Future<void> setBoundingBoxVisibility(bool visible) async {
if (_boundingBoxAsset == null) { if (boundingBoxAsset == null) {
final boundingBox = await getBoundingBox(); final boundingBox = await getBoundingBox();
final min = [ final min = [
boundingBox.centerX - boundingBox.halfExtentX, boundingBox.centerX - boundingBox.halfExtentX,
@@ -277,19 +279,19 @@ class FFIAsset extends ThermionAsset {
primitiveType: PrimitiveType.LINES, primitiveType: PrimitiveType.LINES,
); );
_boundingBoxAsset = await viewer.createGeometry( boundingBoxAsset = await viewer.createGeometry(
geometry, geometry,
materialInstances: [material], materialInstances: [material],
keepData: false, keepData: false,
); ) as FFIAsset;
TransformManager_setParent(Engine_getTransformManager(engine), TransformManager_setParent(Engine_getTransformManager(engine),
_boundingBoxAsset!.entity, entity, false); boundingBoxAsset!.entity, entity, false);
} }
if (visible) { if (visible) {
await _boundingBoxAsset!.addToScene(); await boundingBoxAsset!.addToScene();
} else { } else {
await _boundingBoxAsset!.removeFromScene(); await boundingBoxAsset!.removeFromScene();
} }
} }
} }

View File

@@ -510,8 +510,8 @@ class ThermionViewerFFI extends ThermionViewer {
throw Exception("An error occurred loading the asset at $path"); throw Exception("An error occurred loading the asset at $path");
} }
var thermionAsset = var thermionAsset = FFIAsset(
FFIAsset(asset, _sceneManager!, _engine!, _unlitMaterialProvider!, this); asset, _sceneManager!, _engine!, _unlitMaterialProvider!, this);
return thermionAsset; return thermionAsset;
} }
@@ -973,6 +973,12 @@ class ThermionViewerFFI extends ThermionViewer {
/// ///
@override @override
Future removeAsset(covariant FFIAsset asset) async { Future removeAsset(covariant FFIAsset asset) async {
if (asset.boundingBoxAsset != null) {
await asset.setBoundingBoxVisibility(false);
await withVoidCallback((callback) =>
SceneManager_destroyAssetRenderThread(
_sceneManager!, asset.boundingBoxAsset!.pointer, callback));
}
await withVoidCallback((callback) => SceneManager_destroyAssetRenderThread( await withVoidCallback((callback) => SceneManager_destroyAssetRenderThread(
_sceneManager!, asset.pointer, callback)); _sceneManager!, asset.pointer, callback));
} }
@@ -1641,8 +1647,8 @@ class ThermionViewerFFI extends ThermionViewer {
throw Exception("Failed to create geometry"); throw Exception("Failed to create geometry");
} }
var asset = var asset = FFIAsset(
FFIAsset(assetPtr, _sceneManager!, _engine!, _unlitMaterialProvider!, this); assetPtr, _sceneManager!, _engine!, _unlitMaterialProvider!, this);
return asset; return asset;
} }
@@ -1760,7 +1766,8 @@ class ThermionViewerFFI extends ThermionViewer {
_sceneManager!, material.pointer, cb); _sceneManager!, material.pointer, cb);
} }
}); });
_grid = FFIAsset(ptr, _sceneManager!, _engine!, _unlitMaterialProvider!, this); _grid = FFIAsset(
ptr, _sceneManager!, _engine!, _unlitMaterialProvider!, this);
} }
await _grid!.addToScene(); await _grid!.addToScene();
await setLayerVisibility(VisibilityLayers.OVERLAY, true); await setLayerVisibility(VisibilityLayers.OVERLAY, true);

View File

@@ -134,15 +134,34 @@ void main() async {
}); });
group("bounding box", () { group("bounding box", () {
test('bounding box', () async { test('add bounding box to geometry', () async {
await testHelper.withViewer( await testHelper.withViewer(
(viewer) async { (viewer) async {
final cube = await viewer.createGeometry( final cube = await viewer.createGeometry(
GeometryHelper.cube(normals: false, uvs: false)); GeometryHelper.cube(normals: false, uvs: false));
await cube.setBoundingBoxVisibility(true); await cube.setBoundingBoxVisibility(true);
await testHelper.capture(viewer, "bounding_box_visible"); await testHelper.capture(viewer, "geometry_bounding_box_visible");
await cube.setBoundingBoxVisibility(false); await cube.setBoundingBoxVisibility(false);
await testHelper.capture(viewer, "bounding_box_not_visible"); await testHelper.capture(
viewer, "geometry_bounding_box_not_visible");
await cube.setBoundingBoxVisibility(true);
await viewer.removeAsset(cube);
await testHelper.capture(
viewer, "geometry_bounding_box_removed");
},
postProcessing: true,
);
});
test('add bounding box to gltf', () async {
await testHelper.withViewer(
(viewer) async {
var cube = await viewer
.loadGlb("file://${testHelper.testDir}/assets/cube.glb");
await cube.setBoundingBoxVisibility(true);
await testHelper.capture(viewer, "gltf_bounding_box_visible");
await cube.setBoundingBoxVisibility(false);
await testHelper.capture(viewer, "gltf_bounding_box_not_visible");
}, },
postProcessing: true, postProcessing: true,
); );
@@ -210,7 +229,7 @@ void main() async {
// await testHelper.capture(viewer, "texture_applied_to_geometry"); // await testHelper.capture(viewer, "texture_applied_to_geometry");
// await viewer.removeEntity(cube); // await viewer.removeAsset(cube);
// await viewer.destroyTexture(texture); // await viewer.destroyTexture(texture);
// await viewer.dispose(); // await viewer.dispose();
// }); // });
@@ -319,7 +338,7 @@ void main() async {
// await viewer.setToneMapping(ToneMapper.LINEAR); // await viewer.setToneMapping(ToneMapper.LINEAR);
// final unlit = await viewer.createUnlitMaterialInstance(); // final unlit = await viewer.createUnlitMaterialInstance();
// await viewer.removeEntity(cube); // await viewer.removeAsset(cube);
// cube = await viewer.createGeometry(GeometryHelper.cube(), // cube = await viewer.createGeometry(GeometryHelper.cube(),
// materialInstance: unlit); // materialInstance: unlit);
// var reconstructedTexture = await viewer.createTexture(pixelBufferPng); // var reconstructedTexture = await viewer.createTexture(pixelBufferPng);