web compatibility work

This commit is contained in:
Nick Fisher
2024-05-15 22:29:56 +08:00
parent dcc52cd7c1
commit 5fd0fc60bf
11 changed files with 1945 additions and 689 deletions

View File

@@ -1,12 +1,7 @@
import 'package:vector_math/vector_math_64.dart';
import 'dart:async';
import 'dart:ffi';
import 'package:animation_tools_dart/animation_tools_dart.dart';
import 'package:dart_filament/dart_filament/entities/filament_entity.dart';
import 'package:dart_filament/dart_filament/entities/gizmo.dart';
import 'package:vector_math/vector_math_64.dart';
typedef RenderCallback = Pointer<NativeFunction<Void Function(Pointer<Void>)>>;
// "picking" means clicking/tapping on the viewport, and unprojecting the X/Y coordinate to determine whether any renderable entities were present at those coordinates.
typedef FilamentPickResult = ({FilamentEntity entity, double x, double y});
@@ -39,6 +34,8 @@ class TextureDetails {
}
abstract class AbstractFilamentViewer {
Future<bool> get initialized;
///
/// The result(s) of calling [pick] (see below).
/// This may be a broadcast stream, so you should ensure you have subscribed to this stream before calling [pick].
@@ -598,9 +595,14 @@ abstract class AbstractFilamentViewer {
Future setPriority(FilamentEntity entityId, int priority);
///
/// The Scene holds the transform gizmo and all loaded entities/lights.
/// The Scene holds all loaded entities/lights.
///
Scene get scene;
///
///
///
AbstractGizmo? get gizmo;
}
///
@@ -641,9 +643,16 @@ abstract class Scene {
/// Attach the gizmo to the specified entity.
///
void select(FilamentEntity entity);
///
/// The transform gizmo.
///
Future<Gizmo> get gizmo;
}
abstract class AbstractGizmo {
bool get isActive;
void translate(double transX, double transY);
void reset();
void attach(FilamentEntity entity);
void detach();
}

View File

@@ -3,6 +3,7 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
export 'package:ffi/ffi.dart';
export 'dart:ffi';
export 'dart_filament.g.dart';
final allocator = calloc;
@@ -20,7 +21,7 @@ Future<void> withVoidCallback(
nativeCallable.close();
}
Future<Pointer<Void>> withVoidPointerCallback(
Future<int> withVoidPointerCallback(
Function(Pointer<NativeFunction<Void Function(Pointer<Void>)>>)
func) async {
final completer = Completer<Pointer<Void>>();
@@ -31,9 +32,9 @@ Future<Pointer<Void>> withVoidPointerCallback(
final nativeCallable =
NativeCallable<Void Function(Pointer<Void>)>.listener(callback);
func.call(nativeCallable.nativeFunction);
await completer.future;
var ptr = await completer.future;
nativeCallable.close();
return completer.future;
return ptr.address;
}
Future<bool> withBoolCallback(

View File

@@ -0,0 +1,555 @@
@JS()
library flutter_filament_js;
import 'dart:js_interop';
import 'package:animation_tools_dart/src/morph_animation_data.dart';
import 'package:dart_filament/dart_filament/abstract_filament_viewer.dart';
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';
@JSExport()
class DartFilamentJSExportViewer {
final AbstractFilamentViewer viewer;
static void initializeBindings(AbstractFilamentViewer viewer) {
print("Initializing JS bindings");
var shim = DartFilamentJSExportViewer(viewer);
var wrapper = createJSInteropWrapper<DartFilamentJSExportViewer>(shim)
as DartFilamentJSShim;
globalContext.setProperty("filamentViewer".toJS, wrapper);
print("Set global context property");
}
DartFilamentJSExportViewer(this.viewer);
JSPromise<JSBoolean> get initialized {
return viewer.initialized.then((v) => v.toJS).toJS;
}
@JSExport()
JSBoolean get rendering => viewer.rendering.toJS;
@JSExport()
JSPromise setRendering(bool render) {
return viewer.setRendering(render).toJS;
}
@JSExport()
JSPromise render() => viewer.render().toJS;
@JSExport()
JSPromise setFrameRate(int framerate) => viewer.setFrameRate(framerate).toJS;
@JSExport()
JSPromise dispose() => viewer.dispose().toJS;
@JSExport()
JSPromise setBackgroundImage(String path, {bool fillHeight = false}) =>
viewer.setBackgroundImage(path, fillHeight: fillHeight).toJS;
@JSExport()
JSPromise setBackgroundImagePosition(double x, double y,
{bool clamp = false}) =>
viewer.setBackgroundImagePosition(x, y, clamp: clamp).toJS;
@JSExport()
JSPromise clearBackgroundImage() => viewer.clearBackgroundImage().toJS;
@JSExport()
JSPromise setBackgroundColor(double r, double g, double b, double alpha) =>
viewer.setBackgroundColor(r, g, b, alpha).toJS;
@JSExport()
JSPromise loadSkybox(String skyboxPath) => viewer.loadSkybox(skyboxPath).toJS;
@JSExport()
JSPromise removeSkybox() => viewer.removeSkybox().toJS;
@JSExport()
JSPromise loadIbl(String lightingPath, {double intensity = 30000}) =>
viewer.loadIbl(lightingPath, intensity: intensity).toJS;
@JSExport()
JSPromise rotateIbl(JSArray<JSNumber> rotation) => throw UnimplementedError();
// viewer.rotateIbl(rotation.toDartMatrix3()).toJS;
@JSExport()
JSPromise removeIbl() => viewer.removeIbl().toJS;
@JSExport()
JSPromise<JSNumber> addLight(
int type,
double colour,
double intensity,
double posX,
double posY,
double posZ,
double dirX,
double dirY,
double dirZ,
bool castShadows) {
return viewer
.addLight(type, colour, intensity, posX, posY, posZ, dirX, dirY, dirZ,
castShadows)
.then((entity) => entity.toJS)
.toJS;
}
@JSExport()
JSPromise removeLight(FilamentEntity light) => viewer.removeLight(light).toJS;
@JSExport()
JSPromise clearLights() => viewer.clearLights().toJS;
@JSExport()
JSPromise<JSNumber> loadGlb(String path, {int numInstances = 1}) {
return viewer
.loadGlb(path, numInstances: numInstances)
.then((entity) => entity.toJS)
.toJS;
}
@JSExport()
JSPromise<JSNumber> createInstance(FilamentEntity entity) {
return viewer.createInstance(entity).then((instance) => instance.toJS).toJS;
}
@JSExport()
JSPromise<JSNumber> getInstanceCount(FilamentEntity entity) =>
viewer.getInstanceCount(entity).then((v) => v.toJS).toJS;
@JSExport()
JSPromise<JSArray<JSNumber>> getInstances(FilamentEntity entity) {
return viewer
.getInstances(entity)
.then((instances) =>
instances.map((instance) => instance.toJS).toList().toJS)
.toJS;
}
@JSExport()
JSPromise<JSNumber> loadGltf(String path, String relativeResourcePath,
{bool force = false}) {
return viewer
.loadGltf(path, relativeResourcePath, force: force)
.then((entity) => entity.toJS)
.toJS;
}
@JSExport()
JSPromise panStart(double x, double y) => viewer.panStart(x, y).toJS;
@JSExport()
JSPromise panUpdate(double x, double y) => viewer.panUpdate(x, y).toJS;
@JSExport()
JSPromise panEnd() => viewer.panEnd().toJS;
@JSExport()
JSPromise rotateStart(double x, double y) => viewer.rotateStart(x, y).toJS;
@JSExport()
JSPromise rotateUpdate(double x, double y) => viewer.rotateUpdate(x, y).toJS;
@JSExport()
JSPromise rotateEnd() => viewer.rotateEnd().toJS;
@JSExport()
JSPromise setMorphTargetWeights(
FilamentEntity entity, List<double> weights) =>
viewer.setMorphTargetWeights(entity, weights).toJS;
@JSExport()
JSPromise<JSArray<JSString>> getMorphTargetNames(
FilamentEntity entity, String meshName) =>
viewer
.getMorphTargetNames(entity, meshName)
.then((v) => v.map((s) => s.toJS).toList().toJS)
.toJS;
@JSExport()
JSPromise<JSArray<JSString>> getAnimationNames(FilamentEntity entity) =>
viewer
.getAnimationNames(entity)
.then((v) => v.map((s) => s.toJS).toList().toJS)
.toJS;
@JSExport()
JSPromise<JSNumber> getAnimationDuration(
FilamentEntity entity, int animationIndex) =>
viewer
.getAnimationDuration(entity, animationIndex)
.then((v) => v.toJS)
.toJS;
@JSExport()
JSPromise setMorphAnimationData(
FilamentEntity entity,
JSArray<JSArray<JSNumber>> animation,
JSArray<JSString> morphTargets,
JSArray<JSString> targetMeshNames) =>
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;
@JSExport()
JSPromise resetBones(FilamentEntity entity) => viewer.resetBones(entity).toJS;
@JSExport()
JSPromise addBoneAnimation(FilamentEntity entity, JSObject animation) {
throw Exception();
}
// viewer
// .addBoneAnimation(
// entity,
// BoneAnimationData._fromJSObject(animation),
// )
// .toJS;
@JSExport()
JSPromise removeEntity(FilamentEntity entity) =>
viewer.removeEntity(entity).toJS;
@JSExport()
JSPromise clearEntities() => viewer.clearEntities().toJS;
@JSExport()
JSPromise zoomBegin() => viewer.zoomBegin().toJS;
@JSExport()
JSPromise zoomUpdate(double x, double y, double z) =>
viewer.zoomUpdate(x, y, z).toJS;
@JSExport()
JSPromise zoomEnd() => viewer.zoomEnd().toJS;
@JSExport()
JSPromise playAnimation(FilamentEntity entity, int index,
{bool loop = false,
bool reverse = false,
bool replaceActive = true,
double crossfade = 0.0}) =>
viewer
.playAnimation(
entity,
index,
loop: loop,
reverse: reverse,
replaceActive: replaceActive,
crossfade: crossfade,
)
.toJS;
@JSExport()
JSPromise playAnimationByName(FilamentEntity entity, String name,
{bool loop = false,
bool reverse = false,
bool replaceActive = true,
double crossfade = 0.0}) =>
viewer
.playAnimationByName(
entity,
name,
loop: loop,
reverse: reverse,
replaceActive: replaceActive,
crossfade: crossfade,
)
.toJS;
@JSExport()
JSPromise setAnimationFrame(
FilamentEntity entity, int index, int animationFrame) =>
viewer
.setAnimationFrame(
entity,
index,
animationFrame,
)
.toJS;
@JSExport()
JSPromise stopAnimation(FilamentEntity entity, int animationIndex) =>
viewer.stopAnimation(entity, animationIndex).toJS;
@JSExport()
JSPromise stopAnimationByName(FilamentEntity entity, String name) =>
viewer.stopAnimationByName(entity, name).toJS;
@JSExport()
JSPromise setCamera(FilamentEntity entity, String? name) =>
viewer.setCamera(entity, name).toJS;
@JSExport()
JSPromise setMainCamera() => viewer.setMainCamera().toJS;
@JSExport()
JSPromise<JSNumber> getMainCamera() {
return viewer.getMainCamera().then((camera) => camera.toJS).toJS;
}
@JSExport()
JSPromise setCameraFov(double degrees, double width, double height) =>
viewer.setCameraFov(degrees, width, height).toJS;
@JSExport()
JSPromise setToneMapping(int mapper) =>
viewer.setToneMapping(ToneMapper.values[mapper]).toJS;
@JSExport()
JSPromise setBloom(double bloom) => viewer.setBloom(bloom).toJS;
@JSExport()
JSPromise setCameraFocalLength(double focalLength) =>
viewer.setCameraFocalLength(focalLength).toJS;
@JSExport()
JSPromise setCameraCulling(double near, double far) =>
viewer.setCameraCulling(near, far).toJS;
@JSExport()
JSPromise<JSNumber> getCameraCullingNear() =>
viewer.getCameraCullingNear().then((v) => v.toJS).toJS;
@JSExport()
JSPromise<JSNumber> getCameraCullingFar() =>
viewer.getCameraCullingFar().then((v) => v.toJS).toJS;
@JSExport()
JSPromise setCameraFocusDistance(double focusDistance) =>
viewer.setCameraFocusDistance(focusDistance).toJS;
@JSExport()
JSPromise<JSArray<JSNumber>> getCameraPosition() {
throw UnimplementedError();
// return viewer.getCameraPosition().then((position) => position.toJS).toJS;
}
@JSExport()
JSPromise<JSArray<JSNumber>> getCameraModelMatrix() {
throw UnimplementedError();
// return viewer.getCameraModelMatrix().then((matrix) => matrix.toJSArray<JSNumber>()).toJS;
}
@JSExport()
JSPromise<JSArray<JSNumber>> getCameraViewMatrix() {
throw UnimplementedError();
// return viewer.getCameraViewMatrix().then((matrix) => matrix.toJSArray<JSNumber>()).toJS;
}
@JSExport()
JSPromise<JSArray<JSNumber>> getCameraProjectionMatrix() {
throw UnimplementedError();
// return viewer.getCameraProjectionMatrix().then((matrix) => matrix.toJSArray<JSNumber>()).toJS;
}
@JSExport()
JSPromise<JSArray<JSNumber>> getCameraCullingProjectionMatrix() {
throw UnimplementedError();
// return viewer.getCameraCullingProjectionMatrix().then((matrix) => matrix.toJSArray<JSNumber>()).toJS;
}
@JSExport()
JSPromise<JSNumber> getCameraFrustum() {
throw UnimplementedError();
// return viewer.getCameraFrustum().then((frustum) => frustum.toJS).toJS;
}
@JSExport()
JSPromise setCameraPosition(double x, double y, double z) =>
viewer.setCameraPosition(x, y, z).toJS;
@JSExport()
JSPromise<JSArray<JSNumber>> getCameraRotation() {
return viewer
.getCameraRotation()
.then((rotation) => rotation.storage.map((v) => v.toJS).toList().toJS)
.toJS;
}
@JSExport()
JSPromise moveCameraToAsset(FilamentEntity entity) =>
throw UnimplementedError();
// viewer.moveCameraToAsset(entity)).toJS;
@JSExport()
JSPromise setViewFrustumCulling(JSBoolean enabled) =>
throw UnimplementedError();
// viewer.setViewFrustumCulling(enabled).toJS;
@JSExport()
JSPromise setCameraExposure(
double aperture, double shutterSpeed, double sensitivity) =>
viewer.setCameraExposure(aperture, shutterSpeed, sensitivity).toJS;
@JSExport()
JSPromise setCameraRotation(JSArray<JSNumber> quaternion) =>
throw UnimplementedError();
// viewer.setCameraRotation(quaternion.toDartQuaternion()).toJS;
@JSExport()
JSPromise setCameraModelMatrix(List<double> matrix) =>
viewer.setCameraModelMatrix(matrix).toJS;
@JSExport()
JSPromise setMaterialColor(FilamentEntity entity, String meshName,
int materialIndex, double r, double g, double b, double a) =>
throw UnimplementedError();
// viewer.setMaterialColor(
// entity),
// meshName,
// materialIndex,
// r,
// g,
// b,
// a,
// ).toJS;
@JSExport()
JSPromise transformToUnitCube(FilamentEntity entity) =>
viewer.transformToUnitCube(entity).toJS;
@JSExport()
JSPromise setPosition(FilamentEntity entity, double x, double y, double z) =>
viewer.setPosition(entity, x, y, z).toJS;
@JSExport()
JSPromise setScale(FilamentEntity entity, double scale) =>
viewer.setScale(entity, scale).toJS;
@JSExport()
JSPromise setRotation(
FilamentEntity entity, double rads, double x, double y, double z) =>
viewer.setRotation(entity, rads, x, y, z).toJS;
@JSExport()
JSPromise queuePositionUpdate(
FilamentEntity entity, double x, double y, double z, bool relative) =>
viewer
.queuePositionUpdate(
entity,
x,
y,
z,
relative: relative,
)
.toJS;
@JSExport()
JSPromise queueRotationUpdate(FilamentEntity entity, double rads, double x,
double y, double z, bool relative) =>
viewer
.queueRotationUpdate(
entity,
rads,
x,
y,
z,
relative: relative,
)
.toJS;
@JSExport()
JSPromise queueRotationUpdateQuat(
FilamentEntity entity, JSArray<JSNumber> quat, JSBoolean relative) =>
throw UnimplementedError();
// viewer.queueRotationUpdateQuat(
// entity,
// quat.toDartQuaternion(),
// relative: relative,
// ).toJS;
@JSExport()
JSPromise setPostProcessing(bool enabled) =>
viewer.setPostProcessing(enabled).toJS;
@JSExport()
JSPromise setAntiAliasing(bool msaa, bool fxaa, bool taa) =>
viewer.setAntiAliasing(msaa, fxaa, taa).toJS;
@JSExport()
JSPromise setRotationQuat(
FilamentEntity entity, JSArray<JSNumber> rotation) =>
throw UnimplementedError();
// viewer.setRotationQuat(
// entity,
// rotation.toDartQuaternion(),
// ).toJS;
@JSExport()
JSPromise reveal(FilamentEntity entity, String? meshName) =>
viewer.reveal(entity, meshName).toJS;
@JSExport()
JSPromise hide(FilamentEntity entity, String? meshName) =>
viewer.hide(entity, meshName).toJS;
@JSExport()
void pick(int x, int y) => viewer.pick(x, y);
@JSExport()
String? getNameForEntity(FilamentEntity entity) =>
viewer.getNameForEntity(entity);
@JSExport()
JSPromise setCameraManipulatorOptions({
int mode = 0,
double orbitSpeedX = 0.01,
double orbitSpeedY = 0.01,
double zoomSpeed = 0.01,
}) =>
viewer
.setCameraManipulatorOptions(
mode: ManipulatorMode.values[mode],
orbitSpeedX: orbitSpeedX,
orbitSpeedY: orbitSpeedY,
zoomSpeed: zoomSpeed,
)
.toJS;
@JSExport()
JSPromise<JSArray<JSNumber>> getChildEntities(
FilamentEntity parent, bool renderableOnly) {
return viewer
.getChildEntities(
parent,
renderableOnly,
)
.then((entities) => entities.map((entity) => entity.toJS).toList().toJS)
.toJS;
}
@JSExport()
JSPromise<JSNumber> getChildEntity(FilamentEntity parent, String childName) {
return viewer
.getChildEntity(
parent,
childName,
)
.then((entity) => entity.toJS)
.toJS;
}
@JSExport()
JSPromise<JSArray<JSString>> getChildEntityNames(
FilamentEntity entity, bool renderableOnly) =>
viewer
.getChildEntityNames(
entity,
renderableOnly: renderableOnly,
)
.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 addCollisionComponent(FilamentEntity entity,
{JSFunction? callback, bool affectsTransform = false}) {
throw UnimplementedError();
// final Function? dartCallback = callback != null
// ? allowInterop((int entityId1, int entityId2) => callback.apply([entityId1, entityId2]))
// : null;
// return viewer.addCollisionComponent(
// entity),
// callback: dartCallback,
// affectsTransform: affectsTransform,
// ).toJs
}
}

View File

@@ -0,0 +1,330 @@
@JS()
library flutter_filament_js;
import 'dart:js_interop';
import 'package:dart_filament/dart_filament/entities/filament_entity.dart';
extension type DartFilamentJSShim(JSObject _) implements JSObject {
@JS('initialized')
external JSPromise<JSBoolean> get initialized;
@JS('rendering')
external bool get rendering;
@JS('setRendering')
external JSPromise setRendering(bool render);
@JS('render')
external JSPromise render();
@JS('setFrameRate')
external JSPromise setFrameRate(int framerate);
@JS('dispose')
external JSPromise dispose();
@JS('setBackgroundImage')
external JSPromise setBackgroundImage(String path, bool fillHeight);
@JS('setBackgroundImagePosition')
external JSPromise setBackgroundImagePosition(double x, double y,
bool clamp);
@JS('clearBackgroundImage')
external JSPromise clearBackgroundImage();
@JS('setBackgroundColor')
external JSPromise setBackgroundColor(
double r, double g, double b, double alpha);
@JS('loadSkybox')
external JSPromise loadSkybox(String skyboxPath);
@JS('removeSkybox')
external JSPromise removeSkybox();
@JS('loadIbl')
external JSPromise loadIbl(String lightingPath, double intensity);
@JS('rotateIbl')
external JSPromise rotateIbl(JSArray<JSNumber> rotationMatrix);
@JS('removeIbl')
external JSPromise removeIbl();
@JS('addLight')
external JSPromise<JSNumber> addLight(
int type,
double colour,
double intensity,
double posX,
double posY,
double posZ,
double dirX,
double dirY,
double dirZ,
bool castShadows,
);
@JS('removeLight')
external JSPromise removeLight(FilamentEntity light);
@JS('clearLights')
external JSPromise clearLights();
@JS('loadGlb')
external JSPromise<JSNumber> loadGlb(String path, int numInstances);
@JS('createInstance')
external JSPromise<JSNumber> createInstance(FilamentEntity entity);
@JS('getInstanceCount')
external JSPromise<JSNumber> getInstanceCount(FilamentEntity entity);
@JS('getInstances')
external JSPromise<JSArray<JSNumber>> getInstances(FilamentEntity entity);
@JS('loadGltf')
external JSPromise<JSNumber> loadGltf(
String path,
String relativeResourcePath
);
@JS('panStart')
external JSPromise panStart(double x, double y);
@JS('panUpdate')
external JSPromise panUpdate(double x, double y);
@JS('panEnd')
external JSPromise panEnd();
@JS('rotateStart')
external JSPromise rotateStart(double x, double y);
@JS('rotateUpdate')
external JSPromise rotateUpdate(double x, double y);
@JS('rotateEnd')
external JSPromise rotateEnd();
@JS('setMorphTargetWeights')
external JSPromise setMorphTargetWeights(
FilamentEntity entity, JSArray<JSNumber> weights);
@JS('getMorphTargetNames')
external JSPromise<JSArray<JSString>> getMorphTargetNames(
FilamentEntity entity, String meshName);
@JS('getAnimationNames')
external JSPromise<JSArray<JSString>> getAnimationNames(FilamentEntity entity);
@JS('getAnimationDuration')
external JSPromise<JSNumber> getAnimationDuration(
FilamentEntity entity, int animationIndex);
@JS('setMorphAnimationData')
external JSPromise setMorphAnimationData(
FilamentEntity entity,
JSArray<JSArray<JSNumber>> animation,
JSArray<JSString> morphTargets,
JSArray<JSString>? targetMeshNames,
);
@JS('resetBones')
external JSPromise resetBones(FilamentEntity entity);
@JS('addBoneAnimation')
external JSPromise addBoneAnimation(FilamentEntity entity, JSObject animation);
@JS('removeEntity')
external JSPromise removeEntity(FilamentEntity entity);
@JS('clearEntities')
external JSPromise clearEntities();
@JS('zoomBegin')
external JSPromise zoomBegin();
@JS('zoomUpdate')
external JSPromise zoomUpdate(double x, double y, double z);
@JS('zoomEnd')
external JSPromise zoomEnd();
@JS('playAnimation')
external JSPromise playAnimation(
FilamentEntity entity,
int index,
bool loop,
bool reverse,
bool replaceActive,
double crossfade,
);
@JS('playAnimationByName')
external JSPromise playAnimationByName(
FilamentEntity entity,
String name,
bool loop,
bool reverse,
bool replaceActive,
double crossfade,
);
@JS('setAnimationFrame')
external JSPromise setAnimationFrame(
FilamentEntity entity, int index, int animationFrame);
@JS('stopAnimation')
external JSPromise stopAnimation(FilamentEntity entity, int animationIndex);
@JS('stopAnimationByName')
external JSPromise stopAnimationByName(FilamentEntity entity, String name);
@JS('setCamera')
external JSPromise setCamera(FilamentEntity entity, String? name);
@JS('setMainCamera')
external JSPromise setMainCamera();
@JS('getMainCamera')
external JSPromise<JSNumber> getMainCamera();
@JS('setCameraFov')
external JSPromise setCameraFov(double degrees, double width, double height);
@JS('setToneMapping')
external JSPromise setToneMapping(int mapper);
@JS('setBloom')
external JSPromise setBloom(double bloom);
@JS('setCameraFocalLength')
external JSPromise setCameraFocalLength(double focalLength);
@JS('setCameraCulling')
external JSPromise setCameraCulling(double near, double far);
@JS('getCameraCullingNear')
external JSPromise<JSNumber> getCameraCullingNear();
@JS('getCameraCullingFar')
external JSPromise<JSNumber> getCameraCullingFar();
@JS('setCameraFocusDistance')
external JSPromise setCameraFocusDistance(double focusDistance);
@JS('getCameraPosition')
external JSPromise<JSArray<JSNumber>> getCameraPosition();
@JS('getCameraModelMatrix')
external JSPromise<JSArray<JSNumber>> getCameraModelMatrix();
@JS('getCameraViewMatrix')
external JSPromise<JSArray<JSNumber>> getCameraViewMatrix();
@JS('getCameraProjectionMatrix')
external JSPromise<JSArray<JSNumber>> getCameraProjectionMatrix();
@JS('getCameraCullingProjectionMatrix')
external JSPromise<JSArray<JSNumber>> getCameraCullingProjectionMatrix();
@JS('getCameraFrustum')
external JSPromise<JSObject> getCameraFrustum();
@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(JSBoolean enabled);
@JS('setAntiAliasing')
external JSPromise setAntiAliasing(
JSBoolean msaa, JSBoolean fxaa, JSBoolean 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,
double orbitSpeedX ,
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('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('testCollisions')
external JSPromise testCollisions(FilamentEntity entity);
@JS('setPriority')
external JSPromise setPriority(FilamentEntity entityId, int priority);
}

View File

@@ -0,0 +1,692 @@
import 'dart:js_interop';
import 'dart:js_interop_unsafe';
import 'package:animation_tools_dart/animation_tools_dart.dart';
import 'package:dart_filament/dart_filament/abstract_filament_viewer.dart';
import 'package:dart_filament/dart_filament/entities/filament_entity.dart';
import 'package:dart_filament/dart_filament/scene.dart';
import 'package:vector_math/vector_math_64.dart';
import 'dart_filament_js_extension_type.dart';
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;
}
@override
Future<bool> get initialized async {
var inited = _jsObject.initialized;
final JSBoolean result = await inited.toDart;
return result.toDart;
}
@override
Stream<FilamentPickResult> get pickResult {
throw UnimplementedError();
}
@override
bool get rendering => _jsObject.rendering;
@override
Future<void> setRendering(bool render) async {
await _jsObject.setRendering(render).toDart;
}
@override
Future<void> render() async {
await _jsObject.render().toDart;
}
@override
Future<void> setFrameRate(int framerate) async {
await _jsObject.setFrameRate(framerate).toDart;
}
@override
Future<void> dispose() async {
await _jsObject.dispose().toDart;
}
@override
Future<void> setBackgroundImage(String path,
{bool fillHeight = false}) async {
await _jsObject.setBackgroundImage(path, fillHeight).toDart;
}
@override
Future<void> setBackgroundImagePosition(double x, double y,
{bool clamp = false}) async {
await _jsObject.setBackgroundImagePosition(x, y, clamp).toDart;
}
@override
Future<void> clearBackgroundImage() async {
await _jsObject.clearBackgroundImage().toDart;
}
@override
Future<void> setBackgroundColor(
double r, double g, double b, double alpha) async {
await _jsObject.setBackgroundColor(r, g, b, alpha).toDart;
}
@override
Future<void> loadSkybox(String skyboxPath) async {
await _jsObject.loadSkybox(skyboxPath).toDart;
}
@override
Future<void> removeSkybox() async {
await _jsObject.removeSkybox().toDart;
}
@override
Future<void> loadIbl(String lightingPath, {double intensity = 30000}) async {
await _jsObject.loadIbl(lightingPath, intensity).toDart;
}
@override
Future<void> rotateIbl(Matrix3 rotation) async {
throw UnimplementedError();
// final JSMatrix3 jsRotation = rotation.storage;
// await _jsObject.rotateIbl(jsRotation).toDart;
}
@override
Future<void> removeIbl() async {
await _jsObject.removeIbl().toDart;
}
@override
Future<FilamentEntity> addLight(
int type,
double colour,
double intensity,
double posX,
double posY,
double posZ,
double dirX,
double dirY,
double dirZ,
bool castShadows) async {
return (await _jsObject
.addLight(type, colour, intensity, posX, posY, posZ, dirX, dirY,
dirZ, castShadows)
.toDart)
.toDartInt;
}
@override
Future<void> removeLight(FilamentEntity light) async {
await _jsObject.removeLight(light).toDart;
}
@override
Future<void> clearLights() async {
await _jsObject.clearLights().toDart;
}
@override
Future<FilamentEntity> loadGlb(String path, {int numInstances = 1}) async {
return (await _jsObject.loadGlb(path, numInstances).toDart).toDartInt;
}
@override
Future<FilamentEntity> createInstance(FilamentEntity entity) async {
return (await _jsObject.createInstance(entity).toDart).toDartInt;
}
@override
Future<int> getInstanceCount(FilamentEntity entity) async {
return (await _jsObject.getInstanceCount(entity).toDart).toDartInt;
}
@override
Future<List<FilamentEntity>> getInstances(FilamentEntity entity) async {
throw UnimplementedError();
// final List<JSObject> jsInstances =
// await _jsObject.getInstances(entity).toDart;
// return jsInstances
// .map((js) => FilamentEntity._fromJSObject(js))
// .toList()
// .toDart;
}
@override
Future<FilamentEntity> loadGltf(String path, String relativeResourcePath,
{bool force = false}) async {
throw UnimplementedError();
// final FilamentEntity jsEntity = await _jsObject
// .loadGltf(path, relativeResourcePath, force: force)
// .toDart;
// return FilamentEntity._fromJSObject(jsEntity).toDart;
}
@override
Future<void> panStart(double x, double y) async {
await _jsObject.panStart(x, y).toDart;
}
@override
Future<void> panUpdate(double x, double y) async {
await _jsObject.panUpdate(x, y).toDart;
}
@override
Future<void> panEnd() async {
await _jsObject.panEnd().toDart;
}
@override
Future<void> rotateStart(double x, double y) async {
await _jsObject.rotateStart(x, y).toDart;
}
@override
Future<void> rotateUpdate(double x, double y) async {
await _jsObject.rotateUpdate(x, y).toDart;
}
@override
Future<void> rotateEnd() async {
await _jsObject.rotateEnd().toDart;
}
@override
Future<void> setMorphTargetWeights(
FilamentEntity entity, List<double> weights) async {
throw UnimplementedError();
// JSArray<JSNumber>.withLength(weights.length)
// await _jsObject.setMorphTargetWeights(entity, weights.toJSBox as JSArray<JSNumber>).toDart;
}
@override
Future<List<String>> 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();
}
@override
Future<List<String>> getAnimationNames(FilamentEntity entity) async {
var names = (await (_jsObject.getAnimationNames(entity).toDart))
.toDart
.map((x) => x.toDart)
.toList();
return names;
}
@override
Future<double> getAnimationDuration(
FilamentEntity entity, int animationIndex) async {
return (await _jsObject.getAnimationDuration(entity, animationIndex).toDart)
.toDartDouble;
}
@override
Future<void> setMorphAnimationData(
FilamentEntity entity, MorphAnimationData animation,
{List<String>? 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;
}
@override
Future<void> resetBones(FilamentEntity entity) async {
await _jsObject.resetBones(entity).toDart;
}
@override
Future<void> addBoneAnimation(
FilamentEntity entity, BoneAnimationData animation) async {
throw UnimplementedError();
// await _jsObject.addBoneAnimation(entity, animation).toDart;
}
@override
Future<void> removeEntity(FilamentEntity entity) async {
await _jsObject.removeEntity(entity).toDart;
}
@override
Future<void> clearEntities() async {
await _jsObject.clearEntities().toDart;
}
@override
Future<void> zoomBegin() async {
await _jsObject.zoomBegin().toDart;
}
@override
Future<void> zoomUpdate(double x, double y, double z) async {
await _jsObject.zoomUpdate(x, y, z).toDart;
}
@override
Future<void> zoomEnd() async {
await _jsObject.zoomEnd().toDart;
}
@override
Future<void> playAnimation(FilamentEntity entity, int index,
{bool loop = false,
bool reverse = false,
bool replaceActive = true,
double crossfade = 0.0}) async {
await _jsObject
.playAnimation(entity, index, loop, reverse, replaceActive, crossfade)
.toDart;
}
@override
Future<void> playAnimationByName(FilamentEntity entity, String name,
{bool loop = false,
bool reverse = false,
bool replaceActive = true,
double crossfade = 0.0}) async {
await _jsObject
.playAnimationByName(
entity, name, loop, reverse, replaceActive, crossfade)
.toDart;
}
@override
Future<void> setAnimationFrame(
FilamentEntity entity, int index, int animationFrame) async {
await _jsObject.setAnimationFrame(entity, index, animationFrame).toDart;
}
@override
Future<void> stopAnimation(FilamentEntity entity, int animationIndex) async {
await _jsObject.stopAnimation(entity, animationIndex).toDart;
}
@override
Future<void> stopAnimationByName(FilamentEntity entity, String name) async {
await _jsObject.stopAnimationByName(entity, name).toDart;
}
@override
Future<void> setCamera(FilamentEntity entity, String? name) async {
await _jsObject.setCamera(entity, name).toDart;
}
@override
Future<void> setMainCamera() async {
await _jsObject.setMainCamera().toDart;
}
@override
Future<FilamentEntity> getMainCamera() async {
throw UnimplementedError();
// final FilamentEntity jsEntity = await _jsObject.getMainCamera().toDart;
// return FilamentEntity._fromJSObject(jsEntity).toDart;
}
@override
Future<void> setCameraFov(double degrees, double width, double height) async {
await _jsObject.setCameraFov(degrees, width, height).toDart;
}
@override
Future<void> setToneMapping(ToneMapper mapper) async {
await _jsObject.setToneMapping(mapper.index).toDart;
}
@override
Future<void> setBloom(double bloom) async {
await _jsObject.setBloom(bloom).toDart;
}
@override
Future<void> setCameraFocalLength(double focalLength) async {
await _jsObject.setCameraFocalLength(focalLength).toDart;
}
@override
Future<void> setCameraCulling(double near, double far) async {
await _jsObject.setCameraCulling(near, far).toDart;
}
@override
Future<double> getCameraCullingNear() async {
return (await _jsObject.getCameraCullingNear().toDart).toDartDouble;
}
@override
Future<double> getCameraCullingFar() async {
return (await _jsObject.getCameraCullingFar().toDart).toDartDouble;
}
@override
Future<void> setCameraFocusDistance(double focusDistance) async {
await _jsObject.setCameraFocusDistance(focusDistance).toDart;
}
@override
Future<Vector3> getCameraPosition() async {
final jsPosition = (await _jsObject.getCameraPosition().toDart).toDart;
return Vector3(jsPosition[0].toDartDouble, jsPosition[1].toDartDouble,
jsPosition[2].toDartDouble);
}
@override
Future<Matrix4> getCameraModelMatrix() async {
throw UnimplementedError();
// final JSMatrix4 jsMatrix = await _jsObject.getCameraModelMatrix().toDart;
// return Matrix4.fromList(jsMatrix.storage).toDart;
}
@override
Future<Matrix4> getCameraViewMatrix() async {
throw UnimplementedError();
// final JSMatrix4 jsMatrix = await _jsObject.getCameraViewMatrix().toDart;
// return Matrix4.fromList(jsMatrix.storage).toDart;
}
@override
Future<Matrix4> getCameraProjectionMatrix() async {
throw UnimplementedError();
// final JSMatrix4 jsMatrix =
// await _jsObject.getCameraProjectionMatrix().toDart;
// return Matrix4.fromList(jsMatrix.storage).toDart;
}
@override
Future<Matrix4> getCameraCullingProjectionMatrix() async {
throw UnimplementedError();
// final JSMatrix4 jsMatrix =
// await _jsObject.getCameraCullingProjectionMatrix().toDart;
// return Matrix4.fromList(jsMatrix.storage).toDart;
}
@override
Future<Frustum> getCameraFrustum() async {
throw UnimplementedError();
// final JSObject jsFrustum = await _jsObject.getCameraFrustum().toDart;
// // Assuming Frustum is a class that can be constructed from the JSObject
// return Frustum._fromJSObject(jsFrustum).toDart;
}
@override
Future<void> setCameraPosition(double x, double y, double z) async {
await _jsObject.setCameraPosition(x, y, z).toDart;
}
@override
Future<Matrix3> getCameraRotation() async {
throw UnimplementedError();
// final JSMatrix3 jsRotation = await _jsObject.getCameraRotation().toDart;
// return Matrix3.fromList(jsRotation.storage).toDart;
}
@override
Future<void> moveCameraToAsset(FilamentEntity entity) async {
await _jsObject.moveCameraToAsset(entity).toDart;
}
@override
Future<void> setViewFrustumCulling(bool enabled) async {
throw UnimplementedError();
// await _jsObject.setViewFrustumCulling(enabled.toJSBoolean()).toDart;
}
@override
Future<void> setCameraExposure(
double aperture, double shutterSpeed, double sensitivity) async {
await _jsObject
.setCameraExposure(aperture, shutterSpeed, sensitivity)
.toDart;
}
@override
Future<void> setCameraRotation(Quaternion quaternion) async {
throw UnimplementedError();
// final JSQuaternion jsQuaternion = quaternion.toJSQuaternion().toDart;
// await _jsObject.setCameraRotation(jsQuaternion).toDart;
}
@override
Future<void> setCameraModelMatrix(List<double> matrix) async {
throw UnimplementedError();
// await _jsObject.setCameraModelMatrix(matrix.toJSBox).toDart;
}
@override
Future<void> setMaterialColor(FilamentEntity entity, String meshName,
int materialIndex, double r, double g, double b, double a) async {
await _jsObject
.setMaterialColor(entity, meshName, materialIndex, r, g, b, a)
.toDart;
}
@override
Future<void> transformToUnitCube(FilamentEntity entity) async {
await _jsObject.transformToUnitCube(entity).toDart;
}
@override
Future<void> setPosition(
FilamentEntity entity, double x, double y, double z) async {
await _jsObject.setPosition(entity, x, y, z).toDart;
}
@override
Future<void> setScale(FilamentEntity entity, double scale) async {
await _jsObject.setScale(entity, scale).toDart;
}
@override
Future<void> setRotation(
FilamentEntity entity, double rads, double x, double y, double z) async {
await _jsObject.setRotation(entity, rads, x, y, z).toDart;
}
@override
Future<void> queuePositionUpdate(
FilamentEntity entity, double x, double y, double z,
{bool relative = false}) async {
await _jsObject.queuePositionUpdate(entity, x, y, z, relative).toDart;
}
@override
Future<void> queueRotationUpdate(
FilamentEntity entity, double rads, double x, double y, double z,
{bool relative = false}) async {
await _jsObject.queueRotationUpdate(entity, rads, x, y, z, relative).toDart;
}
@override
Future<void> queueRotationUpdateQuat(FilamentEntity entity, Quaternion quat,
{bool relative = false}) async {
throw UnimplementedError();
// final JSQuaternion jsQuat = quat.toJSQuaternion().toDart;
// await _jsObject
// .queueRotationUpdateQuat(entity, jsQuat, relative: relative)
// .toDart;
}
@override
Future<void> setPostProcessing(bool enabled) async {
throw UnimplementedError();
// await _jsObject.setPostProcessing(enabled.toJSBoolean()).toDart;
}
@override
Future<void> setAntiAliasing(bool msaa, bool fxaa, bool taa) async {
throw UnimplementedError();
// await _jsObject
// .setAntiAliasing(
// msaa.toJSBoolean(), fxaa.toJSBoolean(), taa.toJSBoolean())
// .toDart;
}
@override
Future<void> setRotationQuat(
FilamentEntity entity, Quaternion rotation) async {
throw UnimplementedError();
// final JSQuaternion jsRotation = rotation.toJSQuaternion().toDart;
// await _jsObject.setRotationQuat(entity, jsRotation).toDart;
}
@override
Future<void> reveal(FilamentEntity entity, String? meshName) async {
throw UnimplementedError();
// await _jsObject.reveal(entity, meshName).toDart;
}
@override
Future<void> hide(FilamentEntity entity, String? meshName) async {
throw UnimplementedError();
// await _jsObject.hide(entity, meshName).toDart;
}
@override
void pick(int x, int y) {
throw UnimplementedError();
// _jsObject.pick(x, y).toDart;
}
@override
String? getNameForEntity(FilamentEntity entity) {
throw UnimplementedError();
// return _jsObject.getNameForEntity(entity).toDart;
}
@override
Future<void> setCameraManipulatorOptions(
{ManipulatorMode mode = ManipulatorMode.ORBIT,
double orbitSpeedX = 0.01,
double orbitSpeedY = 0.01,
double zoomSpeed = 0.01}) async {
throw UnimplementedError();
// await _jsObject
// .setCameraManipulatorOptions(
// mode: mode.index,
// orbitSpeedX: orbitSpeedX,
// orbitSpeedY: orbitSpeedY,
// zoomSpeed: zoomSpeed)
// .toDart;
}
@override
Future<List<FilamentEntity>> getChildEntities(
FilamentEntity parent, bool renderableOnly) async {
throw UnimplementedError();
// final List<JSObject> jsEntities = await _jsObject
// .getChildEntities(parent, renderableOnly.toJSBoolean())
// .toDart;
// return jsEntities
// .map((js) => FilamentEntity._fromJSObject(js))
// .toList()
// .toDart;
}
@override
Future<FilamentEntity> getChildEntity(
FilamentEntity parent, String childName) async {
return (await _jsObject.getChildEntity(parent, childName).toDart).toDartInt;
}
@override
Future<List<String>> getChildEntityNames(FilamentEntity entity,
{bool renderableOnly = true}) async {
var names =
await _jsObject.getChildEntityNames(entity, renderableOnly).toDart;
return names.toDart.map((x) => x.toDart).toList();
}
@override
Future<void> setRecording(bool recording) async {
throw UnimplementedError();
// await _jsObject.setRecording(recording.toJSBoolean()).toDart;
}
@override
Future<void> setRecordingOutputDirectory(String outputDirectory) async {
await _jsObject.setRecordingOutputDirectory(outputDirectory).toDart;
}
@override
Future<void> addAnimationComponent(FilamentEntity entity) async {
await _jsObject.addAnimationComponent(entity).toDart;
}
@override
Future<void> addCollisionComponent(FilamentEntity entity,
{void Function(int entityId1, int entityId2)? callback,
bool affectsTransform = false}) async {
throw UnimplementedError();
// final JSFunction? jsCallback = callback != null
// ? allowInterop(
// (int entityId1, int entityId2) => callback(entityId1, entityId2))
// : null;
// await _jsObject
// .addCollisionComponent(entity,
// callback: jsCallback,
// affectsTransform: affectsTransform.toJSBoolean())
// .toDart;
}
@override
Future<void> removeCollisionComponent(FilamentEntity entity) async {
await _jsObject.removeCollisionComponent(entity).toDart;
}
@override
Future<FilamentEntity> createGeometry(
List<double> vertices, List<int> indices,
{String? materialPath,
PrimitiveType primitiveType = PrimitiveType.TRIANGLES}) async {
throw UnimplementedError();
// final FilamentEntity jsEntity = await _jsObject
// .createGeometry(vertices, indices,
// materialPath: materialPath, primitiveType: primitiveType.index)
// .toDart;
// return FilamentEntity._fromJSObject(jsEntity).toDart;
}
@override
Future<void> setParent(FilamentEntity child, FilamentEntity parent) async {
await _jsObject.setParent(child, parent).toDart;
}
@override
Future<void> testCollisions(FilamentEntity entity) async {
await _jsObject.testCollisions(entity).toDart;
}
@override
Future<void> setPriority(FilamentEntity entityId, int priority) async {
await _jsObject.setPriority(entityId, priority).toDart;
}
Scene? _scene;
// @override
Scene get scene {
_scene ??= SceneImpl(this);
return _scene!;
}
AbstractGizmo? get gizmo => null;
}

View File

@@ -0,0 +1,3 @@
import 'package:dart_filament/dart_filament/entities/filament_entity.dart';

View File

@@ -3,11 +3,10 @@ import 'dart:math';
import 'package:dart_filament/dart_filament/entities/filament_entity.dart';
import 'package:dart_filament/dart_filament/abstract_filament_viewer.dart';
import 'package:dart_filament/dart_filament/filament_viewer_impl.dart';
import 'package:vector_math/vector_math_64.dart' as v;
class EntityTransformController {
final FilamentViewer controller;
final AbstractFilamentViewer controller;
final FilamentEntity _entity;
late Timer _ticker;

View File

@@ -1,10 +1,8 @@
import 'package:dart_filament/dart_filament/entities/filament_entity.dart';
import 'package:dart_filament/dart_filament/filament_viewer_impl.dart';
import 'package:vector_math/vector_math_64.dart';
import '../abstract_filament_viewer.dart';
class Gizmo {
class Gizmo extends AbstractGizmo {
final FilamentEntity x;
Vector3 _x = Vector3(0.1, 0, 0);
final FilamentEntity y;
@@ -12,7 +10,7 @@ class Gizmo {
final FilamentEntity z;
Vector3 _z = Vector3(0.0, 0.0, 0.1);
final FilamentViewer controller;
final AbstractFilamentViewer controller;
FilamentEntity? _activeAxis;
FilamentEntity? _activeEntity;

View File

@@ -12,6 +12,8 @@ import 'compatibility/compatibility.dart';
// ignore: constant_identifier_names
const FilamentEntity _FILAMENT_ASSET_ERROR = 0;
typedef RenderCallback = Pointer<NativeFunction<Void Function(Pointer<Void>)>>;
class FilamentViewer extends AbstractFilamentViewer {
final _compat = Compatibility();
@@ -103,23 +105,16 @@ class FilamentViewer extends AbstractFilamentViewer {
create_filament_viewer_ffi(_sharedContext, _driver, uberarchivePtr,
resourceLoader, _renderCallback, _renderCallbackOwner, callback);
});
print(viewer);
if (viewer is int) {
_viewer = Pointer.fromAddress(viewer);
} else {
_viewer = (viewer as Pointer<Void>);
}
_viewer = Pointer.fromAddress(viewer);
allocator.free(uberarchivePtr);
print("Set viewer to $_viewer");
print("Created viewer ${_viewer!.address}");
if (_viewer!.address == 0) {
throw Exception("Failed to create viewer. Check logs for details");
}
_sceneManager = get_scene_manager(_viewer!);
_scene = SceneImpl(null, this, _sceneManager!);
_scene = SceneImpl(this);
await setCameraManipulatorOptions(zoomSpeed: 10.0);
@@ -1139,4 +1134,7 @@ class FilamentViewer extends AbstractFilamentViewer {
Future setPriority(FilamentEntity entityId, int priority) async {
set_priority(_sceneManager!, entityId, priority);
}
@override
AbstractGizmo? get gizmo => null;
}

View File

@@ -1,33 +1,15 @@
import 'dart:async';
import 'package:dart_filament/dart_filament/entities/filament_entity.dart';
import 'package:dart_filament/dart_filament/filament_viewer_impl.dart';
import 'compatibility/compatibility.dart';
import 'entities/gizmo.dart';
import 'abstract_filament_viewer.dart';
///
/// For now, this class just holds the entities that have been loaded (though not necessarily visible in the Filament Scene).
///
class SceneImpl extends Scene {
Gizmo? _gizmo;
Future<Gizmo> get gizmo async {
if (_gizmo == null) {
final out = calloc<Int32>(3);
get_gizmo(_sceneManager!, out);
_gizmo = Gizmo(out[0], out[1], out[2], controller);
calloc.free(out);
}
return _gizmo!;
}
FilamentViewer controller;
AbstractFilamentViewer controller;
final Pointer<Void> _sceneManager;
SceneImpl(this._gizmo, this.controller, this._sceneManager);
SceneImpl(this.controller);
@override
FilamentEntity? selected;
@@ -57,7 +39,7 @@ class SceneImpl extends Scene {
var children = await controller.getChildEntities(entity, true);
if (selected == entity || children.contains(selected)) {
selected = null;
_gizmo?.detach();
controller.gizmo?.detach();
}
_lights.remove(entity);
_onUnloadController.add(entity);
@@ -68,7 +50,8 @@ class SceneImpl extends Scene {
var children = await controller.getChildEntities(entity, true);
if (selected == entity || children.contains(selected)) {
selected = null;
_gizmo?.detach();
controller.gizmo?.detach();
}
_entities.remove(entity);
_onUnloadController.add(entity);
@@ -86,7 +69,7 @@ class SceneImpl extends Scene {
for (final light in _lights) {
if (selected == light) {
selected = null;
_gizmo?.detach();
controller.gizmo?.detach();
}
_onUnloadController.add(light);
}
@@ -99,7 +82,7 @@ class SceneImpl extends Scene {
for (final entity in _entities) {
if (selected == entity) {
selected = null;
_gizmo?.detach();
controller.gizmo?.detach();
}
_onUnloadController.add(entity);
}
@@ -132,7 +115,7 @@ class SceneImpl extends Scene {
@override
void select(FilamentEntity entity) {
selected = entity;
_gizmo?.attach(entity);
controller.gizmo?.attach(entity);
_onUpdatedController.add(true);
}
}