add various bone methods to JS interop

This commit is contained in:
Nick Fisher
2024-06-04 13:15:45 +08:00
parent f31bbccdc9
commit fd06424f28
3 changed files with 215 additions and 18 deletions

View File

@@ -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<JSString> bones,
JSArray<JSString> meshNames,
JSArray<JSArray<JSArray<JSNumber>>> 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<BoneAnimationFrame>().toList())
return (rotation: rot, translation: trans);
})
.cast<BoneAnimationFrame>()
.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<JSArray<JSNumber>> getLocalTransform(FilamentEntity entity) {
return viewer
.getLocalTransform(entity)
.then((t) => t.storage.map((v) => v.toJS).toList().toJS)
.toJS;
}
@JSExport()
JSPromise<JSArray<JSNumber>> getWorldTransform(FilamentEntity entity) {
return viewer
.getWorldTransform(entity)
.then((t) => t.storage.map((v) => v.toJS).toList().toJS)
.toJS;
}
@JSExport()
JSPromise setTransform(FilamentEntity entity, JSArray<JSNumber> 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<JSNumber> 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}) {

View File

@@ -146,10 +146,10 @@ extension type DartFilamentJSShim(JSObject _) implements JSObject {
external JSPromise addBoneAnimation(
FilamentEntity entity,
JSArray<JSString> bones,
JSArray<JSString> meshNames,
JSArray<JSArray<JSArray<JSNumber>>> 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<JSArray<JSNumber>> 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<JSNumber> quaternion);
@JS('setCameraModelMatrix')
external JSPromise setCameraModelMatrix(JSArray<JSNumber> 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<JSNumber> 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<JSNumber> 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<JSArray<JSNumber>> getChildEntities(
FilamentEntity parent, bool renderableOnly);
@JS('getChildEntity')
external JSPromise<JSNumber> getChildEntity(
FilamentEntity parent, String childName);
@JS('getChildEntityNames')
external JSPromise<JSArray<JSString>> 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<JSNumber> createGeometry(JSArray<JSNumber> vertices,
JSArray<JSNumber> indices, String? materialPath, int primitiveType);
@JS('setParent')
external JSPromise setParent(FilamentEntity child, FilamentEntity parent);
@JS('getParent')
external JSPromise<JSNumber> getParent(FilamentEntity child);
@JS('getParent')
external JSPromise<JSNumber> 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<JSArray<JSNumber>> getLocalTransform(
FilamentEntity entity);
@JS('getWorldTransform')
external JSPromise<JSArray<JSNumber>> getWorldTransform(
FilamentEntity entity);
@JS('updateBoneMatrices')
external JSPromise updateBoneMatrices(FilamentEntity entity);
@JS('setTransform')
external JSPromise setTransform(
FilamentEntity entity, JSArray<JSNumber> transform);
@JS('setBoneTransform')
external JSPromise setBoneTransform(
FilamentEntity entity, int boneIndex, JSArray<JSNumber> transform, int skinIndex);
}

View File

@@ -286,18 +286,34 @@ class JsInteropFilamentViewer implements AbstractFilamentViewer {
@override
Future<void> 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<FilamentEntity> getBone(FilamentEntity entity, int boneIndex,
{int skinIndex = 0}) async {
var result = await _jsObject.getBone(entity, boneIndex, skinIndex).toDart;
return result.toDartInt;
}
@override
Future<Matrix4> getInverseBindMatrix(FilamentEntity parent, int boneIndex,
{int skinIndex = 0}) {
// TODO: implement getInverseBindMatrix
throw UnimplementedError();
}
@override
Future<Matrix4> getLocalTransform(FilamentEntity entity) async {
var result = await _jsObject.getLocalTransform(entity).toDart;
return Matrix4.fromList(result.toDart.map((v) => v.toDartDouble).toList());
}
@override
Future<FilamentEntity?> getParent(FilamentEntity child) async {
var result = await _jsObject.getParent(child).toDart;
return result.toDartInt;
}
@override
Future<Matrix4> 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;
}
}