From 3a98bd53de579c33a6bb05cb33eb95de41e58378 Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Fri, 17 May 2024 14:49:40 +0800 Subject: [PATCH] web : mandate child entity for morph animation functions and implement some missing functions --- .../interop/dart_filament_js_export_type.dart | 78 +++++++++++++------ .../dart_filament_js_extension_type.dart | 3 +- .../interop/js_interop_filament_viewer.dart | 63 ++++++++------- 3 files changed, 88 insertions(+), 56 deletions(-) diff --git a/dart_filament/lib/dart_filament/compatibility/web/interop/dart_filament_js_export_type.dart b/dart_filament/lib/dart_filament/compatibility/web/interop/dart_filament_js_export_type.dart index bb615d05..b16f6bd7 100644 --- a/dart_filament/lib/dart_filament/compatibility/web/interop/dart_filament_js_export_type.dart +++ b/dart_filament/lib/dart_filament/compatibility/web/interop/dart_filament_js_export_type.dart @@ -14,12 +14,10 @@ class DartFilamentJSExportViewer { final AbstractFilamentViewer viewer; static void initializeBindings(AbstractFilamentViewer viewer) { - print("Initializing JS bindings"); var shim = DartFilamentJSExportViewer(viewer); var wrapper = createJSInteropWrapper(shim) as DartFilamentJSShim; globalContext.setProperty("filamentViewer".toJS, wrapper); - print("Set global context property"); } DartFilamentJSExportViewer(this.viewer); @@ -163,11 +161,12 @@ class DartFilamentJSExportViewer { @JSExport() JSPromise> getMorphTargetNames( - FilamentEntity entity, String meshName) => - viewer - .getMorphTargetNames(entity, meshName) - .then((v) => v.map((s) => s.toJS).toList().toJS) - .toJS; + FilamentEntity entity, FilamentEntity childEntity) { + var morphTargetNames = viewer + .getMorphTargetNames(entity, childEntity) + .then((v) => v.map((s) => s.toJS).toList().toJS); + return morphTargetNames.toJS; + } @JSExport() JSPromise> getAnimationNames(FilamentEntity entity) => @@ -186,29 +185,52 @@ class DartFilamentJSExportViewer { @JSExport() JSPromise setMorphAnimationData( - FilamentEntity entity, - JSArray> animation, - JSArray morphTargets, - JSArray targetMeshNames) => - viewer + FilamentEntity entity, + JSArray> animation, + JSArray morphTargets, + JSArray? targetMeshNames, + double frameLengthInMs) { + try { + var morphTargetsDart = morphTargets.toDart.map((m) => m.toDart).toList(); + var animationDataDart = animation.toDart + .map((x) => x.toDart.map((y) => y.toDartDouble).toList()) + .toList(); + + var morphAnimationData = MorphAnimationData( + animationDataDart, morphTargetsDart, + frameLengthInMs: frameLengthInMs); + var targetMeshNamesDart = + targetMeshNames?.toDart.map((x) => x.toDart).toList(); + if (animationDataDart.first.length != morphTargetsDart.length) { + throw Exception( + "Length mismatch between morph targets and animation data"); + } + var result = viewer .setMorphAnimationData( - entity, - MorphAnimationData( - animation.toDart - .map((x) => x.toDart.map((y) => y.toDartDouble).toList()) - .toList(), - morphTargets.toDart.map((m) => m.toDart).toList()), - targetMeshNames: - targetMeshNames.toDart.map((x) => x.toDart).toList(), - ) - .toJS; + entity, + morphAnimationData, + targetMeshNames: targetMeshNamesDart, + ) + .onError((err, st) { + print("ERROR SETTING MORPH ANIMATION DATA : $err\n$st"); + return null; + }).then((r) { + print("set morph animation data complete"); + }); + return result.toJS; + } catch (err, st) { + print(err); + print(st); + rethrow; + } + } @JSExport() JSPromise resetBones(FilamentEntity entity) => viewer.resetBones(entity).toJS; @JSExport() JSPromise addBoneAnimation(FilamentEntity entity, JSObject animation) { - throw Exception(); + throw UnimplementedError(); } // viewer // .addBoneAnimation( @@ -508,7 +530,10 @@ class DartFilamentJSExportViewer { renderableOnly, ) .then((entities) => entities.map((entity) => entity.toJS).toList().toJS) - .toJS; + .onError((e, st) async { + print("Error : $e\n$st"); + return [].toJS; + }).toJS; } @JSExport() @@ -519,7 +544,10 @@ class DartFilamentJSExportViewer { childName, ) .then((entity) => entity.toJS) - .toJS; + .onError((e, st) async { + print("Error getChildEntity : $e\n$st"); + return 0.toJS; + }).toJS; } @JSExport() diff --git a/dart_filament/lib/dart_filament/compatibility/web/interop/dart_filament_js_extension_type.dart b/dart_filament/lib/dart_filament/compatibility/web/interop/dart_filament_js_extension_type.dart index acf31da2..5daa72c9 100644 --- a/dart_filament/lib/dart_filament/compatibility/web/interop/dart_filament_js_extension_type.dart +++ b/dart_filament/lib/dart_filament/compatibility/web/interop/dart_filament_js_extension_type.dart @@ -114,7 +114,7 @@ extension type DartFilamentJSShim(JSObject _) implements JSObject { @JS('getMorphTargetNames') external JSPromise> getMorphTargetNames( - FilamentEntity entity, String meshName); + FilamentEntity entity, FilamentEntity childEntity); @JS('getAnimationNames') external JSPromise> getAnimationNames(FilamentEntity entity); @@ -129,6 +129,7 @@ extension type DartFilamentJSShim(JSObject _) implements JSObject { JSArray> animation, JSArray morphTargets, JSArray? targetMeshNames, + double frameLengthInMs ); @JS('resetBones') diff --git a/dart_filament/lib/dart_filament/compatibility/web/interop/js_interop_filament_viewer.dart b/dart_filament/lib/dart_filament/compatibility/web/interop/js_interop_filament_viewer.dart index 69f73214..35991221 100644 --- a/dart_filament/lib/dart_filament/compatibility/web/interop/js_interop_filament_viewer.dart +++ b/dart_filament/lib/dart_filament/compatibility/web/interop/js_interop_filament_viewer.dart @@ -12,8 +12,6 @@ class JsInteropFilamentViewer implements AbstractFilamentViewer { late final DartFilamentJSShim _jsObject; JsInteropFilamentViewer(String globalPropertyName) { - print( - "Initializing interop viewer with global property $globalPropertyName"); this._jsObject = globalContext.getProperty(globalPropertyName.toJS) as DartFilamentJSShim; } @@ -134,7 +132,9 @@ class JsInteropFilamentViewer implements AbstractFilamentViewer { @override Future loadGlb(String path, {int numInstances = 1}) async { - return (await _jsObject.loadGlb(path, numInstances).toDart).toDartInt; + var entity = (await _jsObject.loadGlb(path, numInstances).toDart).toDartInt; + scene.registerEntity(entity); + return entity; } @override @@ -201,18 +201,17 @@ class JsInteropFilamentViewer implements AbstractFilamentViewer { @override Future setMorphTargetWeights( FilamentEntity entity, List weights) async { - throw UnimplementedError(); - - // JSArray.withLength(weights.length) - // await _jsObject.setMorphTargetWeights(entity, weights.toJSBox as JSArray).toDart; + await _jsObject + .setMorphTargetWeights(entity, weights.map((x) => x.toJS).toList().toJS) + .toDart; } @override Future> getMorphTargetNames( - FilamentEntity entity, String meshName) async { - var result = _jsObject.getMorphTargetNames(entity, meshName).toDart; - var dartResult = (await result).toDart; - return dartResult.map((r) => r.toDart).toList(); + FilamentEntity entity, FilamentEntity childEntity) async { + var result = + await _jsObject.getMorphTargetNames(entity, childEntity).toDart; + return result.toDart.map((r) => r.toDart).toList(); } @override @@ -235,16 +234,23 @@ class JsInteropFilamentViewer implements AbstractFilamentViewer { Future setMorphAnimationData( FilamentEntity entity, MorphAnimationData animation, {List? targetMeshNames}) async { - await _jsObject - .setMorphAnimationData( - entity, - animation.data - .map((x) => x.map((y) => y.toJS).toList().toJS) - .toList() - .toJS, - animation.morphTargets.map((x) => x.toJS).toList().toJS, - targetMeshNames?.map((x) => x.toJS).toList().toJS) - .toDart; + try { + var animationDataJs = animation.data + .map((x) => x.map((y) => y.toJS).toList().toJS) + .toList() + .toJS; + var morphTargetsJs = + animation.morphTargets.map((x) => x.toJS).toList().toJS; + var targetMeshNamesJS = targetMeshNames?.map((x) => x.toJS).toList().toJS; + await _jsObject + .setMorphAnimationData(entity, animationDataJs, morphTargetsJs, + targetMeshNamesJS, animation.frameLengthInMs) + .toDart; + } catch (err, st) { + print(err); + print(st); + rethrow; + } } @override @@ -266,7 +272,6 @@ class JsInteropFilamentViewer implements AbstractFilamentViewer { @override Future clearEntities() async { - print("clear entities on js interop side"); await _jsObject.clearEntities().toDart; } @@ -582,14 +587,12 @@ class JsInteropFilamentViewer implements AbstractFilamentViewer { @override Future> getChildEntities( FilamentEntity parent, bool renderableOnly) async { - throw UnimplementedError(); - // final List jsEntities = await _jsObject - // .getChildEntities(parent, renderableOnly.toJSBoolean()) - // .toDart; - // return jsEntities - // .map((js) => FilamentEntity._fromJSObject(js)) - // .toList() - // .toDart; + final children = + await _jsObject.getChildEntities(parent, renderableOnly).toDart; + return children.toDart + .map((js) => js.toDartInt) + .cast() + .toList(); } @override