From fd06424f28a3b87fb16ec2d13cc691218a605983 Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Tue, 4 Jun 2024 13:15:45 +0800 Subject: [PATCH] add various bone methods to JS interop --- .../interop/dart_filament_js_export_type.dart | 83 ++++++++++++++++--- .../dart_filament_js_extension_type.dart | 67 ++++++++++++++- .../interop/js_interop_filament_viewer.dart | 83 ++++++++++++++++++- 3 files changed, 215 insertions(+), 18 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 c6e49e71..7d2448de 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 @@ -11,6 +11,8 @@ import 'package:dart_filament/dart_filament/entities/filament_entity.dart'; import 'package:dart_filament/dart_filament/compatibility/web/interop/dart_filament_js_extension_type.dart'; import 'dart:js_interop_unsafe'; +import 'package:vector_math/vector_math_64.dart'; + @JSExport() class DartFilamentJSExportViewer { final AbstractFilamentViewer viewer; @@ -256,31 +258,35 @@ class DartFilamentJSExportViewer { JSPromise addBoneAnimation( FilamentEntity entity, JSArray bones, - JSArray meshNames, JSArray>> frameData, JSNumber frameLengthInMs, - JSBoolean isModelSpace) { + JSNumber spaceEnum, + JSNumber skinIndex) { var frameDataDart = frameData.toDart - .map((frame) => frame.toDart.map((v) { + .map((frame) => frame.toDart + .map((v) { var values = v.toDart; - var trans = v64.Vector3(values[0].toDartDouble, values[1].toDartDouble, - values[2].toDartDouble); + var trans = v64.Vector3(values[0].toDartDouble, + values[1].toDartDouble, values[2].toDartDouble); var rot = v64.Quaternion( values[3].toDartDouble, values[4].toDartDouble, values[5].toDartDouble, values[6].toDartDouble); - return (rotation:rot, translation:trans); - }).cast().toList()) + return (rotation: rot, translation: trans); + }) + .cast() + .toList()) .toList(); var data = BoneAnimationData( - bones.toDart.map((n) => n.toDart).toList(), - meshNames.toDart.map((n) => n.toDart).toList(), - frameDataDart, - frameLengthInMs.toDartDouble); + bones.toDart.map((n) => n.toDart).toList(), frameDataDart, + frameLengthInMs: frameLengthInMs.toDartDouble, + space: Space.values[spaceEnum.toDartInt]); - return viewer.addBoneAnimation(entity, data).toJS; + return viewer + .addBoneAnimation(entity, data, skinIndex: skinIndex.toDartInt) + .toJS; } @JSExport() @@ -607,15 +613,68 @@ class DartFilamentJSExportViewer { ) .then((v) => v.map((s) => s.toJS).toList().toJS) .toJS; + @JSExport() JSPromise setRecording(bool recording) => viewer.setRecording(recording).toJS; + @JSExport() JSPromise setRecordingOutputDirectory(String outputDirectory) => viewer.setRecordingOutputDirectory(outputDirectory).toJS; + @JSExport() JSPromise addAnimationComponent(FilamentEntity entity) => viewer.addAnimationComponent(entity).toJS; + @JSExport() + JSPromise removeAnimationComponent(FilamentEntity entity) => + viewer.removeAnimationComponent(entity).toJS; + + @JSExport() + JSPromise getParent(FilamentEntity entity) => + viewer.removeAnimationComponent(entity).toJS; + + @JSExport() + JSPromise getBone(FilamentEntity entity, int boneIndex, int skinIndex) => + viewer.getBone(entity, boneIndex, skinIndex: skinIndex).toJS; + + @JSExport() + JSPromise> getLocalTransform(FilamentEntity entity) { + return viewer + .getLocalTransform(entity) + .then((t) => t.storage.map((v) => v.toJS).toList().toJS) + .toJS; + } + + @JSExport() + JSPromise> getWorldTransform(FilamentEntity entity) { + return viewer + .getWorldTransform(entity) + .then((t) => t.storage.map((v) => v.toJS).toList().toJS) + .toJS; + } + + @JSExport() + JSPromise setTransform(FilamentEntity entity, JSArray transform) { + return viewer + .setTransform( + entity, + Matrix4.fromList( + transform.toDart.map((v) => v.toDartDouble).toList())) + .toJS; + } + + @JSExport() + JSPromise updateBoneMatrices(FilamentEntity entity) { + return viewer.updateBoneMatrices(entity).toJS; + } + + @JSExport() + JSPromise setBoneTransform(FilamentEntity entity, + int boneIndex, JSArray transform, int skinIndex) { + return viewer.setBoneTransform(entity, boneIndex, Matrix4.fromList(transform.toDart.map((v) => v.toDartDouble).toList()), + skinIndex: skinIndex).toJS; + } + @JSExport() JSPromise addCollisionComponent(FilamentEntity entity, {JSFunction? callback, bool affectsTransform = false}) { 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 daef31db..f1dc0649 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 @@ -146,10 +146,10 @@ extension type DartFilamentJSShim(JSObject _) implements JSObject { external JSPromise addBoneAnimation( FilamentEntity entity, JSArray bones, - JSArray meshNames, JSArray>> frameData, JSNumber frameLengthInMs, - JSBoolean isModelSpace); + JSNumber spaceEnum, + JSNumber skinIndex); @JS('removeEntity') external JSPromise removeEntity(FilamentEntity entity); @@ -249,56 +249,78 @@ extension type DartFilamentJSShim(JSObject _) implements JSObject { @JS('setCameraPosition') external JSPromise setCameraPosition(double x, double y, double z); + @JS('getCameraRotation') external JSPromise> getCameraRotation(); + @JS('moveCameraToAsset') external JSPromise moveCameraToAsset(FilamentEntity entity); + @JS('setViewFrustumCulling') external JSPromise setViewFrustumCulling(JSBoolean enabled); + @JS('setCameraExposure') external JSPromise setCameraExposure( double aperture, double shutterSpeed, double sensitivity); + @JS('setCameraRotation') external JSPromise setCameraRotation(JSArray quaternion); + @JS('setCameraModelMatrix') external JSPromise setCameraModelMatrix(JSArray matrix); + @JS('setMaterialColor') external JSPromise setMaterialColor(FilamentEntity entity, String meshName, int materialIndex, double r, double g, double b, double a); + @JS('transformToUnitCube') external JSPromise transformToUnitCube(FilamentEntity entity); + @JS('setPosition') external JSPromise setPosition( FilamentEntity entity, double x, double y, double z); + @JS('setScale') external JSPromise setScale(FilamentEntity entity, double scale); + @JS('setRotation') external JSPromise setRotation( FilamentEntity entity, double rads, double x, double y, double z); + @JS('queuePositionUpdate') external JSPromise queuePositionUpdate( FilamentEntity entity, double x, double y, double z, bool relative); + @JS('queueRotationUpdate') external JSPromise queueRotationUpdate(FilamentEntity entity, double rads, double x, double y, double z, bool relative); + @JS('queueRotationUpdateQuat') external JSPromise queueRotationUpdateQuat( FilamentEntity entity, JSArray quat, bool relative); + @JS('setPostProcessing') external JSPromise setPostProcessing(bool enabled); + @JS('setAntiAliasing') external JSPromise setAntiAliasing(bool msaa, bool fxaa, bool taa); + @JS('setRotationQuat') external JSPromise setRotationQuat( FilamentEntity entity, JSArray rotation); + @JS('reveal') external JSPromise reveal(FilamentEntity entity, String? meshName); + @JS('hide') external JSPromise hide(FilamentEntity entity, String? meshName); + @JS('pick') external void pick(int x, int y); + @JS('getNameForEntity') external String? getNameForEntity(FilamentEntity entity); + @JS('setCameraManipulatorOptions') external JSPromise setCameraManipulatorOptions( int mode, @@ -306,32 +328,73 @@ extension type DartFilamentJSShim(JSObject _) implements JSObject { double orbitSpeedY, double zoomSpeed, ); + @JS('getChildEntities') external JSPromise> getChildEntities( FilamentEntity parent, bool renderableOnly); + @JS('getChildEntity') external JSPromise getChildEntity( FilamentEntity parent, String childName); + @JS('getChildEntityNames') external JSPromise> getChildEntityNames( FilamentEntity entity, bool renderableOnly); + @JS('setRecording') external JSPromise setRecording(JSBoolean recording); + @JS('setRecordingOutputDirectory') external JSPromise setRecordingOutputDirectory(String outputDirectory); + @JS('addAnimationComponent') external JSPromise addAnimationComponent(FilamentEntity entity); + + @JS('removeAnimationComponent') + external JSPromise removeAnimationComponent(FilamentEntity entity); + @JS('addCollisionComponent') external JSPromise addCollisionComponent(FilamentEntity entity); + @JS('removeCollisionComponent') external JSPromise removeCollisionComponent(FilamentEntity entity); + @JS('createGeometry') external JSPromise createGeometry(JSArray vertices, JSArray indices, String? materialPath, int primitiveType); + @JS('setParent') external JSPromise setParent(FilamentEntity child, FilamentEntity parent); + + @JS('getParent') + external JSPromise getParent(FilamentEntity child); + + @JS('getParent') + external JSPromise getBone( + FilamentEntity child, int boneIndex, int skinIndex); + @JS('testCollisions') external JSPromise testCollisions(FilamentEntity entity); + @JS('setPriority') external JSPromise setPriority(FilamentEntity entityId, int priority); + + @JS('getLocalTransform') + external JSPromise> getLocalTransform( + FilamentEntity entity); + + @JS('getWorldTransform') + external JSPromise> getWorldTransform( + FilamentEntity entity); + + @JS('updateBoneMatrices') + external JSPromise updateBoneMatrices(FilamentEntity entity); + + @JS('setTransform') + external JSPromise setTransform( + FilamentEntity entity, JSArray transform); + + @JS('setBoneTransform') + external JSPromise setBoneTransform( + FilamentEntity entity, int boneIndex, JSArray transform, int skinIndex); } 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 4bd2fcd4..a30999d3 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 @@ -286,18 +286,34 @@ class JsInteropFilamentViewer implements AbstractFilamentViewer { @override Future addBoneAnimation( - FilamentEntity entity, BoneAnimationData animation) async { + FilamentEntity entity, BoneAnimationData animation, + {int skinIndex = 0}) async { var boneNames = animation.bones.map((n) => n.toJS).toList().toJS; - var meshNames = animation.meshNames.map((n) => n.toJS).toList().toJS; var frameData = animation.frameData .map((frame) => frame - .map((q) => [q.translation[0].toJS, q.translation[1].toJS, q.translation[2].toJS, q.rotation.w.toJS, q.rotation.x.toJS, q.rotation.y.toJS, q.rotation.z.toJS].toJS) + .map((q) => [ + q.translation[0].toJS, + q.translation[1].toJS, + q.translation[2].toJS, + q.rotation.w.toJS, + q.rotation.x.toJS, + q.rotation.y.toJS, + q.rotation.z.toJS + ].toJS) .toList() .toJS) .toList() .toJS; - await _jsObject.addBoneAnimation(entity, boneNames, meshNames, frameData, animation.frameLengthInMs.toJS, animation.isModelSpace.toJS).toDart; + await _jsObject + .addBoneAnimation( + entity, + boneNames, + frameData, + animation.frameLengthInMs.toJS, + animation.space.index.toJS, + skinIndex.toJS) + .toDart; } @override @@ -725,4 +741,63 @@ class JsInteropFilamentViewer implements AbstractFilamentViewer { var result = await _jsObject.getBoneNames(entity, skinIndex).toDart; return result.toDart.map((n) => n.toDart).toList(); } + + @override + Future getBone(FilamentEntity entity, int boneIndex, + {int skinIndex = 0}) async { + var result = await _jsObject.getBone(entity, boneIndex, skinIndex).toDart; + return result.toDartInt; + } + + @override + Future getInverseBindMatrix(FilamentEntity parent, int boneIndex, + {int skinIndex = 0}) { + // TODO: implement getInverseBindMatrix + throw UnimplementedError(); + } + + @override + Future getLocalTransform(FilamentEntity entity) async { + var result = await _jsObject.getLocalTransform(entity).toDart; + return Matrix4.fromList(result.toDart.map((v) => v.toDartDouble).toList()); + } + + @override + Future getParent(FilamentEntity child) async { + var result = await _jsObject.getParent(child).toDart; + return result.toDartInt; + } + + @override + Future getWorldTransform(FilamentEntity entity) async { + var result = await _jsObject.getLocalTransform(entity).toDart; + return Matrix4.fromList(result.toDart.map((v) => v.toDartDouble).toList()); + } + + @override + Future removeAnimationComponent(FilamentEntity entity) { + return _jsObject.removeAnimationComponent(entity).toDart; + } + + @override + Future setBoneTransform( + FilamentEntity entity, int boneIndex, Matrix4 transform, { int skinIndex =0}) { + return _jsObject + .setBoneTransform(entity, boneIndex, + transform.storage.map((v) => v.toJS).toList().toJS) + .toDart; + } + + @override + Future setTransform(FilamentEntity entity, Matrix4 transform) { + return _jsObject + .setTransform( + entity, transform.storage.map((v) => v.toJS).toList().toJS) + .toDart; + } + + @override + Future updateBoneMatrices(FilamentEntity entity) { + return _jsObject.updateBoneMatrices(entity).toDart; + } }