feat: add Dart methods for getRenderableBoundingBox, setParameterInt and setParameterFloat4

This commit is contained in:
Nick Fisher
2024-11-02 10:18:25 +08:00
parent 124938dbc2
commit 6ff04fb76a
5 changed files with 94 additions and 13 deletions

View File

@@ -83,8 +83,15 @@ class ThermionViewerFFI extends ThermionViewer {
this._sharedContext = sharedContext ?? nullptr; this._sharedContext = sharedContext ?? nullptr;
_onPickResultCallable = NativeCallable< _onPickResultCallable = NativeCallable<
Void Function(EntityId entityId, Int x, Int y, Void Function(
Pointer<TView> view, Float depth, Float fragX, Float fragY, Float fragZ)>.listener(_onPickResult); EntityId entityId,
Int x,
Int y,
Pointer<TView> view,
Float depth,
Float fragX,
Float fragY,
Float fragZ)>.listener(_onPickResult);
_initialize(); _initialize();
} }
@@ -300,7 +307,7 @@ class ThermionViewerFFI extends ThermionViewer {
return; return;
} }
_disposing = true; _disposing = true;
await setRendering(false); await setRendering(false);
await clearEntities(); await clearEntities();
await clearLights(); await clearLights();
@@ -1509,17 +1516,38 @@ class ThermionViewerFFI extends ThermionViewer {
} }
void _onPickResult( void _onPickResult(
ThermionEntity entityId, int x, int y, Pointer<TView> viewPtr, double depth, double fragX, double fragY, double fragZ) async { ThermionEntity entityId,
int x,
int y,
Pointer<TView> viewPtr,
double depth,
double fragX,
double fragY,
double fragZ) async {
final view = FFIView(viewPtr, _viewer!); final view = FFIView(viewPtr, _viewer!);
final viewport = await view.getViewport(); final viewport = await view.getViewport();
_pickResultController _pickResultController.add((
.add((entity: entityId, x: x, y: (viewport.height - y), depth: depth, fragX: fragX, fragY: viewport.height - fragY, fragZ: fragZ )); entity: entityId,
x: x,
y: (viewport.height - y),
depth: depth,
fragX: fragX,
fragY: viewport.height - fragY,
fragZ: fragZ
));
} }
late NativeCallable< late NativeCallable<
Void Function(EntityId entityId, Int x, Int y, Pointer<TView> view, Float depth, Float fragX, Float fragY, Float fragZ)> Void Function(
_onPickResultCallable; EntityId entityId,
Int x,
Int y,
Pointer<TView> view,
Float depth,
Float fragX,
Float fragY,
Float fragZ)> _onPickResultCallable;
/// ///
/// ///
@@ -1750,6 +1778,7 @@ class ThermionViewerFFI extends ThermionViewer {
throw Exception("Viewer must not be null"); throw Exception("Viewer must not be null");
} }
var entity = await withIntCallback((callback) => var entity = await withIntCallback((callback) =>
SceneManager_createGeometryRenderThread( SceneManager_createGeometryRenderThread(
_sceneManager!, _sceneManager!,
@@ -1835,6 +1864,18 @@ class ThermionViewerFFI extends ThermionViewer {
set_priority(_sceneManager!, entityId, priority); set_priority(_sceneManager!, entityId, priority);
} }
///
///
///
@override
Future<v64.Aabb3> getRenderableBoundingBox(ThermionEntity entityId) async {
final result =
SceneManager_getRenderableBoundingBox(_sceneManager!, entityId);
return v64.Aabb3.centerAndHalfExtents(
Vector3(result.centerX, result.centerY, result.centerZ),
Vector3(result.halfExtentX, result.halfExtentY, result.halfExtentZ));
}
/// ///
/// ///
/// ///
@@ -2051,9 +2092,11 @@ class ThermionViewerFFI extends ThermionViewer {
/// ///
/// ///
/// ///
Future<ThermionFFIMaterialInstance> createUnlitFixedSizeMaterialInstance() async { Future<ThermionFFIMaterialInstance>
createUnlitFixedSizeMaterialInstance() async {
var instance = await withPointerCallback<TMaterialInstance>((cb) { var instance = await withPointerCallback<TMaterialInstance>((cb) {
SceneManager_createUnlitFixedSizeMaterialInstanceRenderThread(_sceneManager!, cb); SceneManager_createUnlitFixedSizeMaterialInstanceRenderThread(
_sceneManager!, cb);
}); });
if (instance == nullptr) { if (instance == nullptr) {
throw Exception("Failed to create material instance"); throw Exception("Failed to create material instance");
@@ -2205,6 +2248,12 @@ class ThermionFFIMaterialInstance extends MaterialInstance {
MaterialInstance_setDepthWrite(this._pointer, enabled); MaterialInstance_setDepthWrite(this._pointer, enabled);
} }
@override
Future setParameterFloat4(String name, double x, double y, double z, double w) async {
MaterialInstance_setParameterFloat4(
_pointer, name.toNativeUtf8().cast<Char>(), x, y, z, w);
}
@override @override
Future setParameterFloat2(String name, double x, double y) async { Future setParameterFloat2(String name, double x, double y) async {
MaterialInstance_setParameterFloat2( MaterialInstance_setParameterFloat2(
@@ -2216,6 +2265,14 @@ class ThermionFFIMaterialInstance extends MaterialInstance {
MaterialInstance_setParameterFloat( MaterialInstance_setParameterFloat(
_pointer, name.toNativeUtf8().cast<Char>(), value); _pointer, name.toNativeUtf8().cast<Char>(), value);
} }
@override
Future setParameterInt(String name, int value) async {
MaterialInstance_setParameterInt(
_pointer, name.toNativeUtf8().cast<Char>(), value);
}
} }
class FFIRenderTarget extends RenderTarget { class FFIRenderTarget extends RenderTarget {

View File

@@ -1,8 +1,11 @@
abstract class MaterialInstance { abstract class MaterialInstance {
Future setDepthWriteEnabled(bool enabled); Future setDepthWriteEnabled(bool enabled);
Future setDepthCullingEnabled(bool enabled); Future setDepthCullingEnabled(bool enabled);
Future setParameterFloat4(String name, double x, double y, double z, double w);
Future setParameterFloat2(String name, double x, double y); Future setParameterFloat2(String name, double x, double y);
Future setParameterFloat(String name, double x); Future setParameterFloat(String name, double x);
Future setParameterInt(String name, int value);
} }
enum AlphaMode { OPAQUE, MASK, BLEND } enum AlphaMode { OPAQUE, MASK, BLEND }

View File

@@ -790,6 +790,11 @@ abstract class ThermionViewer {
/// ///
void onDispose(Future Function() callback); void onDispose(Future Function() callback);
///
/// Gets the 3D axis aligned bounding box for the given entity.
///
Future<Aabb3> getRenderableBoundingBox(ThermionEntity entity);
/// ///
/// Gets the 2D bounding box (in viewport coordinates) for the given entity. /// Gets the 2D bounding box (in viewport coordinates) for the given entity.
/// ///

View File

@@ -20,10 +20,13 @@ void main() async {
await viewer await viewer
.setCameraRotation(Quaternion.axisAngle(Vector3(1, 0, 0), -pi / 8)); .setCameraRotation(Quaternion.axisAngle(Vector3(1, 0, 0), -pi / 8));
await viewer.setBackgroundColor(1.0, 1.0, 1.0, 1.0); await viewer.setBackgroundColor(1.0, 1.0, 1.0, 1.0);
await viewer final cube = await viewer
.createGeometry(GeometryHelper.cube(normals: false, uvs: false)); .createGeometry(GeometryHelper.cube(normals: false, uvs: false));
await testHelper.capture(viewer, "geometry_cube_no_uv_no_normal"); await testHelper.capture(viewer, "geometry_cube_no_uv_no_normal");
await viewer.removeEntity(cube);
await testHelper.capture(viewer, "geometry_cube_removed");
await viewer.dispose();
}); });
test('create cube (no normals)', () async { test('create cube (no normals)', () async {
@@ -179,5 +182,16 @@ void main() async {
.createGeometry(GeometryHelper.sphere(normals: false, uvs: false)); .createGeometry(GeometryHelper.sphere(normals: false, uvs: false));
await testHelper.capture(viewer, "geometry_sphere_no_normals"); await testHelper.capture(viewer, "geometry_sphere_no_normals");
}); });
test('create geometry instance', () async {
var viewer = await testHelper.createViewer(
cameraPosition: Vector3(0, 0, 6), bg: kRed);
final cube = await viewer
.createGeometry(GeometryHelper.sphere(normals: false, uvs: false));
await viewer.setTransform(cube, Matrix4.translation(Vector3(2, 1, 1)));
final cube2 = await viewer.createInstance(cube);
await viewer.setTransform(cube2, Matrix4.translation(Vector3(-2, 1, 1)));
await testHelper.capture(viewer, "geometry_instance");
});
}); });
} }

View File

@@ -23,8 +23,10 @@ void main() async {
var cube = await viewer.createGeometry(GeometryHelper.cube(), var cube = await viewer.createGeometry(GeometryHelper.cube(),
materialInstance: materialInstance); materialInstance: materialInstance);
await viewer.setMaterialPropertyFloat4( await materialInstance.setParameterFloat4(
cube, "baseColorFactor", 0, 0.0, 1.0, 0.0, 1.0); "baseColorFactor", 0.0, 1.0, 0.0, 1.0);
await materialInstance.setParameterInt(
"baseColorIndex", -1);
await testHelper.capture(viewer, "unlit_material_base_color"); await testHelper.capture(viewer, "unlit_material_base_color");