move showBoundingBox/hideBoundingBox implementation to ThermionViewerFFI
This commit is contained in:
@@ -2,9 +2,11 @@ import 'dart:async';
|
|||||||
import 'package:thermion_dart/src/filament/src/implementation/background_image.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/background_image.dart';
|
||||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_indirect_light.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_indirect_light.dart';
|
||||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_ktx1_bundle.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_ktx1_bundle.dart';
|
||||||
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_material.dart';
|
||||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_skybox.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_skybox.dart';
|
||||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_swapchain.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_swapchain.dart';
|
||||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_texture.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_texture.dart';
|
||||||
|
import 'package:thermion_dart/src/filament/src/interface/scene.dart';
|
||||||
import '../../../../filament/src/implementation/ffi_asset.dart';
|
import '../../../../filament/src/implementation/ffi_asset.dart';
|
||||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_filament_app.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_filament_app.dart';
|
||||||
import '../../../../filament/src/implementation/ffi_scene.dart';
|
import '../../../../filament/src/implementation/ffi_scene.dart';
|
||||||
@@ -504,10 +506,8 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
_assets.remove(asset);
|
_assets.remove(asset);
|
||||||
await scene.remove(asset);
|
await scene.remove(asset);
|
||||||
|
|
||||||
if (asset.boundingBoxAsset != null) {
|
await hideBoundingBox(asset, destroy: true);
|
||||||
await scene.remove(asset.boundingBoxAsset! as FFIAsset);
|
|
||||||
await FilamentApp.instance!.destroyAsset(asset.boundingBoxAsset!);
|
|
||||||
}
|
|
||||||
await FilamentApp.instance!.destroyAsset(asset);
|
await FilamentApp.instance!.destroyAsset(asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -519,10 +519,8 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
_logger.info("Destroying ${_assets.length} assets");
|
_logger.info("Destroying ${_assets.length} assets");
|
||||||
for (final asset in _assets) {
|
for (final asset in _assets) {
|
||||||
await scene.remove(asset);
|
await scene.remove(asset);
|
||||||
if (asset.boundingBoxAsset != null) {
|
await hideBoundingBox(asset, destroy: true);
|
||||||
await scene.remove(asset.boundingBoxAsset! as FFIAsset);
|
|
||||||
await FilamentApp.instance!.destroyAsset(asset.boundingBoxAsset!);
|
|
||||||
}
|
|
||||||
for (final instance in (await asset.getInstances()).cast<FFIAsset>()) {
|
for (final instance in (await asset.getInstances()).cast<FFIAsset>()) {
|
||||||
await scene.remove(instance);
|
await scene.remove(instance);
|
||||||
}
|
}
|
||||||
@@ -790,6 +788,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
Future addToScene(covariant FFIAsset asset) async {
|
Future addToScene(covariant FFIAsset asset) async {
|
||||||
|
_assets.add(asset);
|
||||||
await scene.add(asset);
|
await scene.add(asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -797,8 +796,179 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
Future removeFromScene(covariant FFIAsset asset) async {
|
Future removeFromScene(covariant FFIAsset asset) async {
|
||||||
|
if (!_assets.contains(asset)) {
|
||||||
|
throw Exception("Asset is not attached to this viewer");
|
||||||
|
}
|
||||||
await scene.remove(asset);
|
await scene.remove(asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final _boundingBoxAssets = <ThermionAsset, Completer<ThermionAsset>>{};
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
|
Future showBoundingBox(ThermionAsset asset) async {
|
||||||
|
if (_boundingBoxAssets.containsKey(asset)) {
|
||||||
|
final bbAsset = await _boundingBoxAssets[asset]!.future;
|
||||||
|
await scene.add(bbAsset);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var completer = Completer<ThermionAsset>();
|
||||||
|
_boundingBoxAssets[asset] = completer;
|
||||||
|
|
||||||
|
final boundingBox = await asset.getBoundingBox();
|
||||||
|
|
||||||
|
final min = [
|
||||||
|
boundingBox.center.x + boundingBox.min.x,
|
||||||
|
boundingBox.center.y + boundingBox.min.y,
|
||||||
|
boundingBox.center.z + boundingBox.min.z
|
||||||
|
];
|
||||||
|
final max = [
|
||||||
|
boundingBox.center.x + boundingBox.max.x,
|
||||||
|
boundingBox.center.y + boundingBox.max.y,
|
||||||
|
boundingBox.center.z + boundingBox.max.z
|
||||||
|
];
|
||||||
|
|
||||||
|
// Create vertices for the bounding box wireframe
|
||||||
|
// 8 vertices for a cube
|
||||||
|
final vertices = Float32List(8 * 3);
|
||||||
|
|
||||||
|
// Bottom vertices
|
||||||
|
vertices[0] = min[0];
|
||||||
|
vertices[1] = min[1];
|
||||||
|
vertices[2] = min[2]; // v0
|
||||||
|
vertices[3] = max[0];
|
||||||
|
vertices[4] = min[1];
|
||||||
|
vertices[5] = min[2]; // v1
|
||||||
|
vertices[6] = max[0];
|
||||||
|
vertices[7] = min[1];
|
||||||
|
vertices[8] = max[2]; // v2
|
||||||
|
vertices[9] = min[0];
|
||||||
|
vertices[10] = min[1];
|
||||||
|
vertices[11] = max[2]; // v3
|
||||||
|
|
||||||
|
// Top vertices
|
||||||
|
vertices[12] = min[0];
|
||||||
|
vertices[13] = max[1];
|
||||||
|
vertices[14] = min[2]; // v4
|
||||||
|
vertices[15] = max[0];
|
||||||
|
vertices[16] = max[1];
|
||||||
|
vertices[17] = min[2]; // v5
|
||||||
|
vertices[18] = max[0];
|
||||||
|
vertices[19] = max[1];
|
||||||
|
vertices[20] = max[2]; // v6
|
||||||
|
vertices[21] = min[0];
|
||||||
|
vertices[22] = max[1];
|
||||||
|
vertices[23] = max[2]; // v7
|
||||||
|
|
||||||
|
// Indices for lines (24 indices for 12 lines)
|
||||||
|
final indices = Uint16List.fromList([
|
||||||
|
// Bottom face
|
||||||
|
0, 1, 1, 2, 2, 3, 3, 0,
|
||||||
|
// Top face
|
||||||
|
4, 5, 5, 6, 6, 7, 7, 4,
|
||||||
|
// Vertical edges
|
||||||
|
0, 4, 1, 5, 2, 6, 3, 7
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Create unlit material instance for the wireframe
|
||||||
|
final materialInstancePtr =
|
||||||
|
await withPointerCallback<TMaterialInstance>((cb) {
|
||||||
|
MaterialProvider_createMaterialInstanceRenderThread(
|
||||||
|
app.ubershaderMaterialProvider,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
cb);
|
||||||
|
});
|
||||||
|
|
||||||
|
final material = FFIMaterialInstance(materialInstancePtr, app);
|
||||||
|
await material.setParameterFloat4(
|
||||||
|
"baseColorFactor", 1.0, 1.0, 0.0, 1.0); // Yellow wireframe
|
||||||
|
|
||||||
|
// Create geometry for the bounding box
|
||||||
|
final geometry = Geometry(
|
||||||
|
vertices,
|
||||||
|
indices,
|
||||||
|
primitiveType: PrimitiveType.LINES,
|
||||||
|
);
|
||||||
|
|
||||||
|
final bbAsset = await FilamentApp.instance!.createGeometry(
|
||||||
|
geometry,
|
||||||
|
animationManager,
|
||||||
|
materialInstances: [material],
|
||||||
|
keepData: false,
|
||||||
|
) as FFIAsset;
|
||||||
|
|
||||||
|
await bbAsset.setCastShadows(false);
|
||||||
|
await bbAsset.setReceiveShadows(false);
|
||||||
|
|
||||||
|
TransformManager_setParent(Engine_getTransformManager(app.engine),
|
||||||
|
bbAsset.entity, asset.entity, false);
|
||||||
|
geometry.uvs.free();
|
||||||
|
geometry.normals.free();
|
||||||
|
geometry.vertices.free();
|
||||||
|
geometry.indices.free();
|
||||||
|
completer.complete(bbAsset);
|
||||||
|
|
||||||
|
await scene.add(bbAsset);
|
||||||
|
|
||||||
|
return bbAsset;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future hideBoundingBox(ThermionAsset asset, {bool destroy = false}) async {
|
||||||
|
if (_boundingBoxAssets.containsKey(asset)) {
|
||||||
|
final completer = _boundingBoxAssets[asset]!;
|
||||||
|
final bbAsset = await completer.future;
|
||||||
|
|
||||||
|
await scene.remove(bbAsset);
|
||||||
|
if (destroy) {
|
||||||
|
_boundingBoxAssets.remove(asset);
|
||||||
|
await FilamentApp.instance!.destroyAsset(bbAsset);
|
||||||
|
_logger.info("Bounding box destroyed");
|
||||||
|
} else {
|
||||||
|
_logger.info("Bounding box hidden");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_logger.warning("Warning - no bounding box for asset created");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ViewerDisposedException implements Exception {}
|
class ViewerDisposedException implements Exception {}
|
||||||
|
|||||||
Reference in New Issue
Block a user