From 102429e090566da585a408424301b0cc2ae3f63e Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Wed, 19 Mar 2025 15:42:11 +0800 Subject: [PATCH] refactoring --- thermion_dart/lib/src/filament/src/asset.dart | 74 ++++--- .../lib/src/filament/src/filament_app.dart | 32 ++- thermion_dart/lib/src/filament/src/view.dart | 2 + .../src/input/src/delegate_input_handler.dart | 11 +- .../fixed_orbit_camera_rotation_delegate.dart | 29 ++- .../free_flight_camera_delegate.dart | 34 ++- .../implementations/gizmo_input_handler.dart | 29 ++- thermion_dart/lib/src/utils/src/axis.dart | 43 ---- thermion_dart/lib/src/utils/utils.dart | 1 - .../viewer/src/ffi/src/background_image.dart | 100 +++++---- .../lib/src/viewer/src/ffi/src/ffi_asset.dart | 158 +++++++------- .../viewer/src/ffi/src/ffi_filament_app.dart | 128 ++++++----- .../lib/src/viewer/src/ffi/src/ffi_gizmo.dart | 22 +- .../lib/src/viewer/src/ffi/src/ffi_scene.dart | 8 +- .../lib/src/viewer/src/ffi/src/ffi_view.dart | 7 + .../src/viewer/src/ffi/src/grid_overlay.dart | 7 +- .../viewer/src/ffi/src/thermion_dart.g.dart | 68 ++++++ .../src/ffi/src/thermion_viewer_ffi.dart | 109 +++++----- .../src/viewer/src/thermion_viewer_base.dart | 37 ++-- .../src/viewer/src/thermion_viewer_stub.dart | 199 +----------------- 20 files changed, 508 insertions(+), 590 deletions(-) delete mode 100644 thermion_dart/lib/src/utils/src/axis.dart diff --git a/thermion_dart/lib/src/filament/src/asset.dart b/thermion_dart/lib/src/filament/src/asset.dart index 4345de5b..694f5df3 100644 --- a/thermion_dart/lib/src/filament/src/asset.dart +++ b/thermion_dart/lib/src/filament/src/asset.dart @@ -3,17 +3,27 @@ library; import 'package:animation_tools_dart/animation_tools_dart.dart'; import 'package:thermion_dart/src/filament/src/layers.dart'; import 'package:thermion_dart/thermion_dart.dart'; -import 'package:vector_math/vector_math_64.dart'; -import 'entity.dart'; export 'geometry.dart'; export 'gltf.dart'; -export 'light_options.dart'; - +/// +/// Represents a renderable object (i.e. not cameras or lights). +/// +/// At a low level, Filament works with entities. In practice, +/// it can be difficult to work directly with these at a higher level +/// because: +/// a) certain objects don't map exactly to entities (e.g. glTF assets, which +/// are represented by a hierarchy of entities). +/// b) it is not trivial to create instances directly from entities +/// +/// [ThermionAsset] is intended to provide a unified high-level interface +/// for working with renderable objects. +/// +/// abstract class ThermionAsset { /// - /// + /// The top-most entity in the hierarchy. If this is a glTF asset /// ThermionEntity get entity; @@ -22,6 +32,11 @@ abstract class ThermionAsset { /// Future> getChildEntities(); + /// + /// + /// + Future getChildEntity(String childName); + /// /// /// @@ -95,7 +110,7 @@ abstract class ThermionAsset { /// /// Schedules the glTF animation at [index] in [asset] to start playing on the next frame. /// - Future playAnimation(ThermionAsset asset, int index, + Future playAnimation(int index, {bool loop = false, bool reverse = false, bool replaceActive = true, @@ -105,7 +120,7 @@ abstract class ThermionAsset { /// /// Schedules the glTF animation at [index] in [entity] to start playing on the next frame. /// - Future playAnimationByName(covariant ThermionAsset asset, String name, + Future playAnimationByName(String name, {bool loop = false, bool reverse = false, bool replaceActive = true, @@ -114,20 +129,19 @@ abstract class ThermionAsset { /// /// /// - Future setGltfAnimationFrame( - covariant ThermionAsset asset, int index, int animationFrame); + Future setGltfAnimationFrame(int index, int animationFrame); /// /// /// - Future stopAnimation(covariant ThermionAsset asset, int animationIndex); + Future stopAnimation(int animationIndex); /// /// /// - Future stopAnimationByName(covariant ThermionAsset asset, String name); + Future stopAnimationByName(String name); - /// + /// /// Set the weights for all morph targets in [entity] to [weights]. /// Note that [weights] must contain values for ALL morph targets, but no exception will be thrown if you don't do so (you'll just get incorrect results). /// If you only want to set one value, set all others to zero (check [getMorphTargetNames] if you need the get a list of all morph targets). @@ -137,27 +151,24 @@ abstract class ThermionAsset { Future setMorphTargetWeights(ThermionEntity entity, List weights); /// - /// Gets the names of all morph targets for the child renderable [childEntity] under [entity]. + /// Gets the names of all morph targets for [entity] (which must be a renderable entity) /// - Future> getMorphTargetNames( - covariant ThermionAsset asset, ThermionEntity childEntity); + Future> getMorphTargetNames({ThermionEntity? entity}); /// - /// Gets the names of all bones for the armature at [skinIndex] under the specified [entity]. + /// Gets the names of all bones for the skin at [skinIndex]. /// - Future> getBoneNames(covariant ThermionAsset asset, - {int skinIndex = 0}); + Future> getBoneNames({int skinIndex = 0}); /// /// Gets the names of all glTF animations embedded in the specified entity. /// - Future> getAnimationNames(covariant ThermionAsset asset); + Future> getAnimationNames(); /// /// Returns the length (in seconds) of the animation at the given index. /// - Future getAnimationDuration( - covariant ThermionAsset asset, int animationIndex); + Future getAnimationDuration(int animationIndex); /// /// Construct animation(s) for every entity under [asset]. If [targetMeshNames] is provided, only entities with matching names will be animated. @@ -166,8 +177,7 @@ abstract class ThermionAsset { /// throwing an exception if any cannot be found. /// It is permissible for [animation] to omit any targets that do exist under [meshName]; these simply won't be animated. /// - Future setMorphAnimationData( - covariant ThermionAsset asset, MorphAnimationData animation, + Future setMorphAnimationData(MorphAnimationData animation, {List? targetMeshNames}); /// @@ -179,7 +189,7 @@ abstract class ThermionAsset { /// Resets all bones in the given entity to their rest pose. /// This should be done before every call to addBoneAnimation. /// - Future resetBones(ThermionAsset asset); + Future resetBones(); /// /// Enqueues and plays the [animation] for the specified bone(s). @@ -199,7 +209,7 @@ abstract class ThermionAsset { /// This will be applied in reverse after [fadeOutInSecs]. /// /// - Future addBoneAnimation(ThermionAsset asset, BoneAnimationData animation, + Future addBoneAnimation(BoneAnimationData animation, {int skinIndex = 0, double fadeInInSecs = 0.0, double fadeOutInSecs = 0.0, @@ -209,32 +219,29 @@ abstract class ThermionAsset { /// Gets the entity representing the bone at [boneIndex]/[skinIndex]. /// The returned entity is only intended for use with [getWorldTransform]. /// - Future getBone(covariant ThermionAsset asset, int boneIndex, - {int skinIndex = 0}); + Future getBone(int boneIndex, {int skinIndex = 0}); /// /// Gets the local (relative to parent) transform for [entity]. /// - Future getLocalTransform(ThermionEntity entity); + Future getLocalTransform({ThermionEntity? entity}); /// /// Gets the world transform for [entity]. /// - Future getWorldTransform(ThermionEntity entity); + Future getWorldTransform({ThermionEntity? entity}); /// /// Gets the inverse bind (pose) matrix for the bone. /// Note that [parent] must be the ThermionEntity returned by [loadGlb/loadGltf], not any other method ([getChildEntity] etc). /// This is because all joint information is internally stored with the parent entity. /// - Future getInverseBindMatrix( - covariant ThermionAsset asset, int boneIndex, - {int skinIndex = 0}); + Future getInverseBindMatrix(int boneIndex, {int skinIndex = 0}); /// /// Sets the transform (relative to its parent) for [entity]. /// - Future setTransform(ThermionEntity entity, Matrix4 transform); + Future setTransform(Matrix4 transform, {ThermionEntity? entity}); /// /// Updates the bone matrices for [entity] (which must be the ThermionEntity @@ -264,4 +271,3 @@ abstract class ThermionAsset { /// Future removeAnimationComponent(ThermionEntity entity); } - diff --git a/thermion_dart/lib/src/filament/src/filament_app.dart b/thermion_dart/lib/src/filament/src/filament_app.dart index 1ae80081..03cc4dd5 100644 --- a/thermion_dart/lib/src/filament/src/filament_app.dart +++ b/thermion_dart/lib/src/filament/src/filament_app.dart @@ -1,5 +1,4 @@ import 'dart:typed_data'; - import 'package:thermion_dart/src/filament/src/engine.dart'; import 'package:thermion_dart/thermion_dart.dart'; @@ -29,7 +28,6 @@ class FilamentConfig { } abstract class FilamentApp { - static FilamentApp? instance; final T engine; @@ -170,13 +168,6 @@ abstract class FilamentApp { Future getMaterialInstanceAt( ThermionEntity entity, int index); - /// - /// - /// - @override - Future createGeometry(Geometry geometry, - {List? materialInstances, bool keepData = false}); - /// /// /// @@ -206,4 +197,27 @@ abstract class FilamentApp { /// /// Future unregisterRequestFrameHook(Future Function() hook); + + /// + /// Retrieves the name assigned to the given entity (usually corresponds to the glTF mesh name). + /// + String? getNameForEntity(ThermionEntity entity); + + /// + /// Gets the parent entity of [entity]. Returns null if the entity has no parent. + /// + Future getParent(ThermionEntity entity); + + /// + /// Gets the ancestor (ultimate parent) entity of [entity]. Returns null if the entity has no parent. + /// + Future getAncestor(ThermionEntity entity); + + /// + /// Sets the parent transform of [child] to [parent]. + /// + Future setParent(ThermionEntity child, ThermionEntity? parent, + {bool preserveScaling}); + + Future createImageMaterialInstance(); } diff --git a/thermion_dart/lib/src/filament/src/view.dart b/thermion_dart/lib/src/filament/src/view.dart index e34bef75..5f678459 100644 --- a/thermion_dart/lib/src/filament/src/view.dart +++ b/thermion_dart/lib/src/filament/src/view.dart @@ -1,4 +1,5 @@ import 'package:thermion_dart/src/filament/src/layers.dart'; +import 'package:thermion_dart/src/filament/src/scene.dart'; import 'package:thermion_dart/thermion_dart.dart'; /// @@ -18,6 +19,7 @@ class Viewport { enum QualityLevel { LOW, MEDIUM, HIGH, ULTRA } abstract class View { + Future getScene(); Future getViewport(); Future setViewport(int width, int height); Future getRenderTarget(); diff --git a/thermion_dart/lib/src/input/src/delegate_input_handler.dart b/thermion_dart/lib/src/input/src/delegate_input_handler.dart index 9fec5807..a67e18ce 100644 --- a/thermion_dart/lib/src/input/src/delegate_input_handler.dart +++ b/thermion_dart/lib/src/input/src/delegate_input_handler.dart @@ -1,8 +1,6 @@ import 'dart:async'; import 'package:logging/logging.dart'; import 'package:thermion_dart/thermion_dart.dart'; -import 'package:vector_math/vector_math_64.dart'; - import 'implementations/fixed_orbit_camera_rotation_delegate.dart'; import 'implementations/free_flight_camera_delegate.dart'; @@ -64,7 +62,7 @@ class DelegateInputHandler implements InputHandler { _inputDeltas[gestureType] = Vector3.zero(); } - viewer.registerRequestFrameHook(process); + FilamentApp.instance!.registerRequestFrameHook(process); } factory DelegateInputHandler.fixedOrbit(ThermionViewer viewer, @@ -75,7 +73,7 @@ class DelegateInputHandler implements InputHandler { DelegateInputHandler( viewer: viewer, pickDelegate: pickDelegate, - transformDelegate: FixedOrbitRotateInputHandlerDelegate(viewer, + transformDelegate: FixedOrbitRotateInputHandlerDelegate(viewer.view, minimumDistance: minimumDistance), actions: { InputType.MMB_HOLD_AND_MOVE: InputAction.ROTATE, @@ -96,9 +94,8 @@ class DelegateInputHandler implements InputHandler { DelegateInputHandler( viewer: viewer, pickDelegate: pickDelegate, - transformDelegate: FreeFlightInputHandlerDelegate(viewer, + transformDelegate: FreeFlightInputHandlerDelegate(viewer.view, clampY: clampY, - entity: entity, rotationSensitivity: rotateSensitivity, zoomSensitivity: zoomSensitivity, panSensitivity: panSensitivity, @@ -245,7 +242,7 @@ class DelegateInputHandler implements InputHandler { @override Future dispose() async { - viewer.unregisterRequestFrameHook(process); + FilamentApp.instance!.unregisterRequestFrameHook(process); } @override diff --git a/thermion_dart/lib/src/input/src/implementations/fixed_orbit_camera_rotation_delegate.dart b/thermion_dart/lib/src/input/src/implementations/fixed_orbit_camera_rotation_delegate.dart index 9b631cc5..196fc5be 100644 --- a/thermion_dart/lib/src/input/src/implementations/fixed_orbit_camera_rotation_delegate.dart +++ b/thermion_dart/lib/src/input/src/implementations/fixed_orbit_camera_rotation_delegate.dart @@ -10,8 +10,7 @@ import '../input_handler.dart'; /// point. /// class FixedOrbitRotateInputHandlerDelegate implements InputHandlerDelegate { - final ThermionViewer viewer; - late Future _camera; + final View view; final double minimumDistance; late final Vector3 target; @@ -24,20 +23,17 @@ class FixedOrbitRotateInputHandlerDelegate implements InputHandlerDelegate { Timer? _updateTimer; FixedOrbitRotateInputHandlerDelegate( - this.viewer, { + this.view, { Vector3? target, this.minimumDistance = 10.0, this.rotationSensitivity = 0.01, this.zoomSensitivity = 0.1, }) { this.target = target ?? Vector3.zero(); - _camera = viewer.getMainCamera().then((Camera cam) async { - var viewMatrix = makeViewMatrix(Vector3(0.0, 0, -minimumDistance), - this.target, Vector3(0.0, 1.0, 0.0)); - viewMatrix.invert(); - await cam.setTransform(viewMatrix); - return cam; + view.getCamera().then((camera) { + camera.lookAt(Vector3(0.0, 0, -minimumDistance), + focus: this.target, up: Vector3(0.0, 1.0, 0.0)); }); } @@ -81,12 +77,13 @@ class FixedOrbitRotateInputHandlerDelegate implements InputHandlerDelegate { _executing = true; - final view = await viewer.getViewAt(0); + final camera = await view.getCamera(); + final viewport = await view.getViewport(); - var viewMatrix = await viewer.getCameraViewMatrix(); - var modelMatrix = await viewer.getCameraModelMatrix(); - var projectionMatrix = await viewer.getCameraProjectionMatrix(); + var viewMatrix = await camera.getViewMatrix(); + var modelMatrix = await camera.getModelMatrix(); + var projectionMatrix = await camera.getProjectionMatrix(); var inverseProjectionMatrix = projectionMatrix.clone()..invert(); Vector3 currentPosition = modelMatrix.getTranslation(); @@ -117,14 +114,14 @@ class FixedOrbitRotateInputHandlerDelegate implements InputHandlerDelegate { Matrix4 newViewMatrix = makeViewMatrix(currentPosition, target, up); newViewMatrix.invert(); - await (await _camera).setModelMatrix(newViewMatrix); + await camera.setModelMatrix(newViewMatrix); updatedModelMatrix = newViewMatrix; } } else if (_queuedRotationDelta.length != 0) { double rotateX = _queuedRotationDelta.x * rotationSensitivity; double rotateY = _queuedRotationDelta.y * rotationSensitivity; - var modelMatrix = await viewer.getCameraModelMatrix(); + var modelMatrix = await camera.getModelMatrix(); // for simplicity, we always assume a fixed coordinate system where // we are rotating around world Y and camera X @@ -136,7 +133,7 @@ class FixedOrbitRotateInputHandlerDelegate implements InputHandlerDelegate { .asRotationMatrix()); modelMatrix = rot1 * rot2 * modelMatrix; - await (await _camera).setModelMatrix(modelMatrix); + await camera.setModelMatrix(modelMatrix); updatedModelMatrix = modelMatrix; } diff --git a/thermion_dart/lib/src/input/src/implementations/free_flight_camera_delegate.dart b/thermion_dart/lib/src/input/src/implementations/free_flight_camera_delegate.dart index f064fed7..8fa3852d 100644 --- a/thermion_dart/lib/src/input/src/implementations/free_flight_camera_delegate.dart +++ b/thermion_dart/lib/src/input/src/implementations/free_flight_camera_delegate.dart @@ -5,8 +5,8 @@ import '../delegates.dart'; import '../input_handler.dart'; class FreeFlightInputHandlerDelegate implements InputHandlerDelegate { - final ThermionViewer viewer; - late Future entity; + final View view; + final Vector3? minBounds; final Vector3? maxBounds; final double rotationSensitivity; @@ -20,21 +20,14 @@ class FreeFlightInputHandlerDelegate implements InputHandlerDelegate { double _queuedZoomDelta = 0.0; Vector3 _queuedMoveDelta = Vector3.zero(); - FreeFlightInputHandlerDelegate(this.viewer, + FreeFlightInputHandlerDelegate(this.view, {this.minBounds, this.maxBounds, this.rotationSensitivity = 0.001, this.movementSensitivity = 0.1, this.zoomSensitivity = 0.1, this.panSensitivity = 0.1, - this.clampY, - ThermionEntity? entity}) { - if (entity != null) { - this.entity = Future.value(entity); - } else { - this.entity = viewer.getMainCameraEntity(); - } - } + this.clampY}) {} @override Future queue(InputAction action, Vector3? delta) async { @@ -76,9 +69,9 @@ class FreeFlightInputHandlerDelegate implements InputHandlerDelegate { return null; } - final activeCamera = await viewer.getActiveCamera(); + final activeCamera = await view.getCamera(); - Matrix4 current = await viewer.getLocalTransform(await entity); + Matrix4 current = await activeCamera.getModelMatrix(); Vector3 relativeTranslation = Vector3.zero(); Quaternion relativeRotation = Quaternion.identity(); @@ -121,17 +114,18 @@ class FreeFlightInputHandlerDelegate implements InputHandlerDelegate { _queuedMoveDelta = Vector3.zero(); } - // If the managed entity is not the active camera, we need to apply the rotation from the current camera model matrix - // to the entity's translation - if (await entity != activeCamera.getEntity()) { - Matrix4 modelMatrix = await activeCamera.getModelMatrix(); - relativeTranslation = modelMatrix.getRotation() * relativeTranslation; - } + // // If the managed entity is not the active camera, we need to apply the rotation from the current camera model matrix + // // to the entity's translation + // if (await entity != activeCamera.getEntity()) { + // Matrix4 modelMatrix = await activeCamera.getModelMatrix(); + // relativeTranslation = modelMatrix.getRotation() * relativeTranslation; + // } var updated = Matrix4.compose( relativeTranslation, relativeRotation, Vector3(1, 1, 1)) * current; - await viewer.setTransform(await entity, updated); + + await activeCamera.setModelMatrix(updated); _executing = false; return updated; diff --git a/thermion_dart/lib/src/input/src/implementations/gizmo_input_handler.dart b/thermion_dart/lib/src/input/src/implementations/gizmo_input_handler.dart index 562b6f8a..098eae36 100644 --- a/thermion_dart/lib/src/input/src/implementations/gizmo_input_handler.dart +++ b/thermion_dart/lib/src/input/src/implementations/gizmo_input_handler.dart @@ -1,7 +1,6 @@ import 'dart:async'; import 'dart:math'; import 'package:thermion_dart/thermion_dart.dart'; -import 'package:vector_math/vector_math_64.dart'; class _Gizmo { final ThermionViewer viewer; @@ -16,7 +15,7 @@ class _Gizmo { _Gizmo(this._gizmo, this.viewer, this.type); static Future<_Gizmo> forType(ThermionViewer viewer, GizmoType type) async { - final view = await viewer.getViewAt(0); + final view = await viewer.view; return _Gizmo(await viewer.createGizmo(view, type), viewer, type); } @@ -26,12 +25,14 @@ class _Gizmo { } Future hide() async { - await _gizmo.removeFromScene(); + final scene = await viewer.view.getScene(); + await scene.remove(_gizmo); } Future reveal() async { - await _gizmo.addToScene(); - gizmoTransform = await viewer.getWorldTransform(_gizmo.entity); + final scene = await viewer.view.getScene(); + await scene.add(_gizmo); + gizmoTransform = await _gizmo.getWorldTransform(); } double _getAngleBetweenVectors(Vector2 v1, Vector2 v2) { @@ -76,17 +77,17 @@ class _Gizmo { await _updateRotation(currentPosition, delta); } - await viewer.setTransform(_gizmo.entity, gizmoTransform!); + await _gizmo.setTransform(gizmoTransform!); transformUpdates.add((transform: gizmoTransform!)); } Future? _updateTranslation( Vector2 currentPosition, Vector2 delta) async { - var view = await viewer.getViewAt(0); + var view = await viewer.view; var camera = await viewer.getActiveCamera(); var viewport = await view.getViewport(); - var projectionMatrix = await viewer.getCameraProjectionMatrix(); + var projectionMatrix = await camera.getProjectionMatrix(); var viewMatrix = await camera.getViewMatrix(); var inverseViewMatrix = await camera.getModelMatrix(); var inverseProjectionMatrix = projectionMatrix.clone()..invert(); @@ -121,10 +122,9 @@ class _Gizmo { } Future? _updateRotation(Vector2 currentPosition, Vector2 delta) async { - var view = await viewer.getViewAt(0); - var camera = await viewer.getActiveCamera(); - var viewport = await view.getViewport(); - var projectionMatrix = await viewer.getCameraProjectionMatrix(); + var camera = await viewer.view.getCamera(); + var viewport = await viewer.view.getViewport(); + var projectionMatrix = await camera.getProjectionMatrix(); var viewMatrix = await camera.getViewMatrix(); // Get gizmo center in screen space @@ -187,7 +187,6 @@ class _Gizmo { } class GizmoInputHandler extends InputHandler { - final ThermionViewer viewer; late final _gizmos = {}; @@ -202,7 +201,7 @@ class GizmoInputHandler extends InputHandler { } _attached = entity; if (_active != null) { - await viewer.setParent(_attached!, _active!._gizmo.entity); + await FilamentApp.instance!.setParent(_attached!, _active!._gizmo.entity); await _active!.reveal(); } } @@ -215,7 +214,7 @@ class GizmoInputHandler extends InputHandler { if (_attached == null) { return; } - await viewer.setParent(_attached!, 0); + await FilamentApp.instance!.setParent(_attached!, null); await _active?.hide(); _attached = null; } diff --git a/thermion_dart/lib/src/utils/src/axis.dart b/thermion_dart/lib/src/utils/src/axis.dart deleted file mode 100644 index f4e7a34d..00000000 --- a/thermion_dart/lib/src/utils/src/axis.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'dart:typed_data'; - -import 'package:vector_math/vector_math_64.dart'; - -import '../../viewer/viewer.dart'; - -class AxisWidget { - final ThermionViewer _viewer; - final ThermionEntity xAxis; - final ThermionEntity yAxis; - final ThermionEntity zAxis; - - AxisWidget._(this.xAxis, this.yAxis, this.zAxis, this._viewer); - - static Future create(ThermionViewer viewer) async { - final xAxis = await viewer.createGeometry( - Geometry(Float32List.fromList([0, 0, 0, 10, 0, 0]), [0, 1], - primitiveType: PrimitiveType.LINES), - materialInstances: [await viewer.createUnlitMaterialInstance()]); - final yAxis = await viewer.createGeometry( - Geometry(Float32List.fromList([0, 0, 0, 0, 10, 0]), [0, 1], - primitiveType: PrimitiveType.LINES), - materialInstances: [await viewer.createUnlitMaterialInstance()]); - final zAxis = await viewer.createGeometry( - Geometry(Float32List.fromList([0, 0, 0, 0, 0, 10]), [0, 1], - primitiveType: PrimitiveType.LINES), - materialInstances: [await viewer.createUnlitMaterialInstance()]); - throw Exception("TODO"); - // await viewer!.setMaterialPropertyFloat4( - // xAxis, "baseColorFactor", 0, 1.0, 0.0, 0.0, 1.0); - // await viewer!.setMaterialPropertyFloat4( - // yAxis, "baseColorFactor", 0, 0.0, 1.0, 0.0, 1.0); - // await viewer!.setMaterialPropertyFloat4( - // zAxis, "baseColorFactor", 0, 0.0, 0.0, 1.0, 1.0); - // return Axis._(xAxis, yAxis, zAxis, viewer); - } - - Future setTransform(Matrix4 transform) async { - await _viewer.setTransform(xAxis, transform); - await _viewer.setTransform(yAxis, transform); - await _viewer.setTransform(zAxis, transform); - } -} diff --git a/thermion_dart/lib/src/utils/utils.dart b/thermion_dart/lib/src/utils/utils.dart index 232b0dd1..60b14d72 100644 --- a/thermion_dart/lib/src/utils/utils.dart +++ b/thermion_dart/lib/src/utils/utils.dart @@ -1,5 +1,4 @@ library; export 'src/geometry.dart'; -export 'src/axis.dart'; export 'src/image.dart'; diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/background_image.dart b/thermion_dart/lib/src/viewer/src/ffi/src/background_image.dart index 92ffb695..208a35a4 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/background_image.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/background_image.dart @@ -5,25 +5,23 @@ import 'package:animation_tools_dart/src/morph_animation_data.dart'; import 'package:thermion_dart/src/filament/src/layers.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_asset.dart'; -import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart'; -import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_material.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_scene.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_texture.dart'; import 'package:thermion_dart/thermion_dart.dart'; class BackgroundImage extends ThermionAsset { final ThermionAsset asset; + ThermionEntity get entity => asset.entity; Texture? _backgroundImageTexture; - FFIMaterial? _imageMaterial; + FFITextureSampler? _imageSampler; final FFIScene scene; - final FilamentApp app; - BackgroundImage._(this.asset, this.scene, this.app, - this._backgroundImageTexture, this._imageMaterial, this._imageSampler); + BackgroundImage._( + this.asset, this.scene, this._backgroundImageTexture, this._imageSampler); Future destroy() async { Scene_removeEntity(scene.scene, entity); @@ -32,33 +30,39 @@ class BackgroundImage extends ThermionAsset { } static Future create( - FFIFilamentApp app, FFIScene scene, Uint8List imageData) async { - final image = await app.decodeImage(imageData); - var backgroundImageTexture = await app.createTexture( - await image.getWidth(), await image.getHeight()); - var imageMaterial = FFIMaterial(Material_createImageMaterial(), app); - var imageSampler = await app.createTextureSampler() as FFITextureSampler; + ThermionViewer viewer, FFIScene scene, Uint8List imageData) async { + final image = await FilamentApp.instance!.decodeImage(imageData); + var backgroundImageTexture = await FilamentApp.instance! + .createTexture(await image.getWidth(), await image.getHeight()); + + var imageSampler = + await FilamentApp.instance!.createTextureSampler() as FFITextureSampler; var imageMaterialInstance = - await imageMaterial!.createInstance() as FFIMaterialInstance; + await FilamentApp.instance!.createImageMaterialInstance(); + await imageMaterialInstance.setParameterTexture( - "image", - backgroundImageTexture as FFITexture, - imageSampler as FFITextureSampler); + "image", backgroundImageTexture as FFITexture, imageSampler); var backgroundImage = - await app.createGeometry(GeometryHelper.fullscreenQuad()) as FFIAsset; + await viewer.createGeometry(GeometryHelper.fullscreenQuad()); backgroundImage.setMaterialInstanceAt(imageMaterialInstance); - await scene.add(backgroundImage); - return BackgroundImage._(backgroundImage, scene, app, - backgroundImageTexture, imageMaterial, imageSampler); + await scene.add(backgroundImage as FFIAsset); + return BackgroundImage._( + backgroundImage, scene, backgroundImageTexture, imageSampler); } + /// + /// + /// @override Future createInstance( {covariant List? materialInstances = null}) { throw UnimplementedError(); } + /// + /// + /// @override Future> getChildEntities() async { return []; @@ -129,7 +133,11 @@ class BackgroundImage extends ThermionAsset { } @override - Future addBoneAnimation(ThermionAsset asset, BoneAnimationData animation, {int skinIndex = 0, double fadeInInSecs = 0.0, double fadeOutInSecs = 0.0, double maxDelta = 1.0}) { + Future addBoneAnimation(BoneAnimationData animation, + {int skinIndex = 0, + double fadeInInSecs = 0.0, + double fadeOutInSecs = 0.0, + double maxDelta = 1.0}) { // TODO: implement addBoneAnimation throw UnimplementedError(); } @@ -141,61 +149,76 @@ class BackgroundImage extends ThermionAsset { } @override - Future getAnimationDuration(covariant ThermionAsset asset, int animationIndex) { + Future getAnimationDuration(int animationIndex) { // TODO: implement getAnimationDuration throw UnimplementedError(); } @override - Future> getAnimationNames(covariant ThermionAsset asset) { + Future> getAnimationNames() { // TODO: implement getAnimationNames throw UnimplementedError(); } @override - Future getBone(covariant ThermionAsset asset, int boneIndex, {int skinIndex = 0}) { + Future getBone(int boneIndex, {int skinIndex = 0}) { // TODO: implement getBone throw UnimplementedError(); } @override - Future> getBoneNames(covariant ThermionAsset asset, {int skinIndex = 0}) { + Future> getBoneNames({int skinIndex = 0}) { // TODO: implement getBoneNames throw UnimplementedError(); } @override - Future getInverseBindMatrix(covariant ThermionAsset asset, int boneIndex, {int skinIndex = 0}) { + Future getChildEntity(String childName) { + // TODO: implement getChildEntity + throw UnimplementedError(); + } + + @override + Future getInverseBindMatrix(int boneIndex, {int skinIndex = 0}) { // TODO: implement getInverseBindMatrix throw UnimplementedError(); } @override - Future getLocalTransform(ThermionEntity entity) { + Future getLocalTransform({ThermionEntity? entity}) { // TODO: implement getLocalTransform throw UnimplementedError(); } @override - Future> getMorphTargetNames(covariant ThermionAsset asset, ThermionEntity childEntity) { + Future> getMorphTargetNames({ThermionEntity? entity}) { // TODO: implement getMorphTargetNames throw UnimplementedError(); } @override - Future getWorldTransform(ThermionEntity entity) { + Future getWorldTransform({ThermionEntity? entity}) { // TODO: implement getWorldTransform throw UnimplementedError(); } @override - Future playAnimation(ThermionAsset asset, int index, {bool loop = false, bool reverse = false, bool replaceActive = true, double crossfade = 0.0, double startOffset = 0.0}) { + Future playAnimation(int index, + {bool loop = false, + bool reverse = false, + bool replaceActive = true, + double crossfade = 0.0, + double startOffset = 0.0}) { // TODO: implement playAnimation throw UnimplementedError(); } @override - Future playAnimationByName(covariant ThermionAsset asset, String name, {bool loop = false, bool reverse = false, bool replaceActive = true, double crossfade = 0.0}) { + Future playAnimationByName(String name, + {bool loop = false, + bool reverse = false, + bool replaceActive = true, + double crossfade = 0.0}) { // TODO: implement playAnimationByName throw UnimplementedError(); } @@ -207,25 +230,28 @@ class BackgroundImage extends ThermionAsset { } @override - Future resetBones(ThermionAsset asset) { + Future resetBones() { // TODO: implement resetBones throw UnimplementedError(); } @override - Future setBoneTransform(ThermionEntity entity, int boneIndex, Matrix4 transform, {int skinIndex = 0}) { + Future setBoneTransform( + ThermionEntity entity, int boneIndex, Matrix4 transform, + {int skinIndex = 0}) { // TODO: implement setBoneTransform throw UnimplementedError(); } @override - Future setGltfAnimationFrame(covariant ThermionAsset asset, int index, int animationFrame) { + Future setGltfAnimationFrame(int index, int animationFrame) { // TODO: implement setGltfAnimationFrame throw UnimplementedError(); } @override - Future setMorphAnimationData(covariant ThermionAsset asset, MorphAnimationData animation, {List? targetMeshNames}) { + Future setMorphAnimationData(MorphAnimationData animation, + {List? targetMeshNames}) { // TODO: implement setMorphAnimationData throw UnimplementedError(); } @@ -243,13 +269,13 @@ class BackgroundImage extends ThermionAsset { } @override - Future stopAnimation(covariant ThermionAsset asset, int animationIndex) { + Future stopAnimation(int animationIndex) { // TODO: implement stopAnimation throw UnimplementedError(); } @override - Future stopAnimationByName(covariant ThermionAsset asset, String name) { + Future stopAnimationByName(String name) { // TODO: implement stopAnimationByName throw UnimplementedError(); } diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/ffi_asset.dart b/thermion_dart/lib/src/viewer/src/ffi/src/ffi_asset.dart index 7fec1f28..5598c2de 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/ffi_asset.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/ffi_asset.dart @@ -1,5 +1,7 @@ import 'dart:typed_data'; +import 'package:animation_tools_dart/animation_tools_dart.dart'; +import 'package:logging/logging.dart'; import 'package:thermion_dart/src/filament/src/layers.dart'; import 'package:thermion_dart/src/utils/src/matrix.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart'; @@ -8,10 +10,8 @@ import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_material.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_viewer_ffi.dart'; import 'package:thermion_dart/thermion_dart.dart'; import 'package:vector_math/vector_math_64.dart' as v64; -import 'package:vector_math/vector_math_64.dart'; class FFIAsset extends ThermionAsset { - /// /// /// @@ -22,6 +22,11 @@ class FFIAsset extends ThermionAsset { /// final FFIFilamentApp app; + /// + /// + /// + final Pointer animationManager; + /// /// /// @@ -37,10 +42,13 @@ class FFIAsset extends ThermionAsset { /// late final ThermionEntity entity; + late final _logger = Logger(this.runtimeType.toString()); + /// /// /// - FFIAsset(this.asset, this.app, {this.isInstance = false}) { + FFIAsset(this.asset, this.app, this.animationManager, + {this.isInstance = false}) { entity = SceneAsset_getEntity(asset); } @@ -59,8 +67,7 @@ class FFIAsset extends ThermionAsset { /// /// @override - Future getChildEntity( - FFIAsset asset, String childName) async { + Future getChildEntity(String childName) async { final childEntities = await getChildEntities(); for (final entity in childEntities) { var name = NameComponentManager_getName(app.nameComponentManager, entity); @@ -71,6 +78,9 @@ class FFIAsset extends ThermionAsset { return null; } + /// + /// + /// @override Future getInstance(int index) async { if (isInstance) { @@ -81,7 +91,7 @@ class FFIAsset extends ThermionAsset { if (instance == nullptr) { throw Exception("No instance available at index $index"); } - return FFIAsset(instance, app); + return FFIAsset(instance, app, animationManager); } /// @@ -111,7 +121,7 @@ class FFIAsset extends ThermionAsset { if (created == FILAMENT_ASSET_ERROR) { throw Exception("Failed to create instance"); } - return FFIAsset(created, app); + return FFIAsset(created, app, animationManager); } /// @@ -129,7 +139,7 @@ class FFIAsset extends ThermionAsset { Future> getInstances() async { var count = await getInstanceCount(); final result = List.generate(count, (i) { - return FFIAsset(SceneAsset_getInstance(asset, i), app); + return FFIAsset(SceneAsset_getInstance(asset, i), app, animationManager); }); return result; @@ -163,7 +173,7 @@ class FFIAsset extends ThermionAsset { var targetEntity = this.entity; if (entityIndex != null) { final childEntities = await this.getChildEntities(); - targetEntity = childEntities[entityIndex!]; + targetEntity = childEntities[entityIndex]; } var sourceMaterialInstance = FFIMaterialInstance( RenderableManager_getMaterialInstanceAt( @@ -209,7 +219,7 @@ class FFIAsset extends ThermionAsset { if (entityIndex != null) { var highlightChildEntities = await _highlight!.getChildEntities(); - targetHighlightEntity = highlightChildEntities[entityIndex!]; + targetHighlightEntity = highlightChildEntities[entityIndex]; } RenderableManager_setPriority( @@ -397,7 +407,8 @@ class FFIAsset extends ThermionAsset { /// /// Future transformToUnitCube() async { - TransformManager_transformToUnitCube(app.transformManager, entity, SceneAsset_getBoundingBox(asset)); + TransformManager_transformToUnitCube( + app.transformManager, entity, SceneAsset_getBoundingBox(asset)); } /// @@ -439,33 +450,35 @@ class FFIAsset extends ThermionAsset { /// /// @override - Future> getMorphTargetNames( - covariant FFIAsset asset, ThermionEntity childEntity) async { + Future> getMorphTargetNames({ThermionEntity? entity}) async { var names = []; + entity ??= this.entity; + var count = AnimationManager_getMorphTargetNameCount( - animationManager, asset.asset, childEntity); + animationManager, asset, entity); var outPtr = allocator(255); for (int i = 0; i < count; i++) { AnimationManager_getMorphTargetName( - animationManager, asset.asset, childEntity, outPtr, i); + animationManager, asset, entity, outPtr, i); names.add(outPtr.cast().toDartString()); } allocator.free(outPtr); return names.cast(); } - Future> getBoneNames(covariant FFIAsset asset, - {int skinIndex = 0}) async { + /// + /// + /// + Future> getBoneNames({int skinIndex = 0}) async { var count = - AnimationManager_getBoneCount(animationManager, asset.asset, skinIndex); + AnimationManager_getBoneCount(animationManager, asset, skinIndex); var out = allocator>(count); for (int i = 0; i < count; i++) { out[i] = allocator(255); } - AnimationManager_getBoneNames( - animationManager, asset.asset, out, skinIndex); + AnimationManager_getBoneNames(animationManager, asset, out, skinIndex); var names = []; for (int i = 0; i < count; i++) { var namePtr = out[i]; @@ -478,14 +491,13 @@ class FFIAsset extends ThermionAsset { /// /// @override - Future> getAnimationNames(covariant FFIAsset asset) async { + Future> getAnimationNames() async { var animationCount = - AnimationManager_getAnimationCount(animationManager, asset.asset); + AnimationManager_getAnimationCount(animationManager, asset); var names = []; var outPtr = allocator(255); for (int i = 0; i < animationCount; i++) { - AnimationManager_getAnimationName( - animationManager, asset.asset, outPtr, i); + AnimationManager_getAnimationName(animationManager, asset, outPtr, i); names.add(outPtr.cast().toDartString()); } allocator.free(outPtr); @@ -497,24 +509,26 @@ class FFIAsset extends ThermionAsset { /// /// @override - Future getAnimationDuration( - FFIAsset asset, int animationIndex) async { + Future getAnimationDuration(int animationIndex) async { return AnimationManager_getAnimationDuration( - animationManager, asset.asset, animationIndex); + animationManager, asset, animationIndex); } /// /// /// - Future getAnimationDurationByName(FFIAsset asset, String name) async { - var animations = await getAnimationNames(asset); + Future getAnimationDurationByName(String name) async { + var animations = await getAnimationNames(); var index = animations.indexOf(name); if (index == -1) { throw Exception("Failed to find animation $name"); } - return getAnimationDuration(asset, index); + return getAnimationDuration(index); } + /// + /// + /// Future clearMorphAnimationData(ThermionEntity entity) async { if (!AnimationManager_clearMorphAnimation(animationManager, entity)) { throw Exception("Failed to clear morph animation"); @@ -525,11 +539,13 @@ class FFIAsset extends ThermionAsset { /// /// @override - Future setMorphAnimationData(FFIAsset asset, MorphAnimationData animation, + Future setMorphAnimationData(MorphAnimationData animation, {List? targetMeshNames}) async { - var meshEntities = await getChildEntities(asset); + var meshEntities = await getChildEntities(); - var meshNames = meshEntities.map((e) => getNameForEntity(e)).toList(); + var meshNames = meshEntities + .map((e) => FilamentApp.instance!.getNameForEntity(e)) + .toList(); if (targetMeshNames != null) { for (final targetMeshName in targetMeshNames) { if (!meshNames.contains(targetMeshName)) { @@ -554,7 +570,7 @@ class FFIAsset extends ThermionAsset { continue; } - var meshMorphTargets = await getMorphTargetNames(asset, meshEntity); + var meshMorphTargets = await getMorphTargetNames(entity: meshEntity); var intersection = animation.morphTargets .toSet() @@ -598,7 +614,7 @@ class FFIAsset extends ThermionAsset { /// Currently, scale is not supported. /// @override - Future addBoneAnimation(covariant FFIAsset asset, BoneAnimationData animation, + Future addBoneAnimation(BoneAnimationData animation, {int skinIndex = 0, double fadeOutInSecs = 0.0, double fadeInInSecs = 0.0, @@ -610,10 +626,10 @@ class FFIAsset extends ThermionAsset { if (skinIndex != 0) { throw UnimplementedError("TODO - support skinIndex != 0 "); } - var boneNames = await getBoneNames(asset); + var boneNames = await getBoneNames(); var restLocalTransformsRaw = allocator(boneNames.length * 16); - AnimationManager_getRestLocalTransforms(animationManager, asset.asset, - skinIndex, restLocalTransformsRaw, boneNames.length); + AnimationManager_getRestLocalTransforms(animationManager, asset, skinIndex, + restLocalTransformsRaw, boneNames.length); var restLocalTransforms = []; for (int i = 0; i < boneNames.length; i++) { @@ -630,7 +646,7 @@ class FFIAsset extends ThermionAsset { var data = allocator(numFrames * 16); var bones = await Future.wait(List>.generate( - boneNames.length, (i) => getBone(asset, i))); + boneNames.length, (i) => getBone(i))); for (int i = 0; i < animation.bones.length; i++) { var boneName = animation.bones[i]; @@ -645,13 +661,15 @@ class FFIAsset extends ThermionAsset { var world = Matrix4.identity(); // this odd use of ! is intentional, without it, the WASM optimizer gets in trouble - var parentBoneEntity = (await getParent(boneEntity))!; + var parentBoneEntity = + (await FilamentApp.instance!.getParent(boneEntity))!; while (true) { if (!bones.contains(parentBoneEntity!)) { break; } world = restLocalTransforms[bones.indexOf(parentBoneEntity!)] * world; - parentBoneEntity = (await getParent(parentBoneEntity))!; + parentBoneEntity = + (await FilamentApp.instance!.getParent(parentBoneEntity))!; } world = Matrix4.identity()..setRotation(world.getRotation()); @@ -677,7 +695,7 @@ class FFIAsset extends ThermionAsset { AnimationManager_addBoneAnimation( animationManager, - asset.asset, + asset, skinIndex, entityBoneIndex, data, @@ -693,7 +711,8 @@ class FFIAsset extends ThermionAsset { /// /// /// - Future getLocalTransform(ThermionEntity entity) async { + Future getLocalTransform({ThermionEntity? entity}) async { + entity ??= this.entity; return double4x4ToMatrix4( TransformManager_getLocalTransform(app.transformManager, entity)); } @@ -701,7 +720,8 @@ class FFIAsset extends ThermionAsset { /// /// /// - Future getWorldTransform(ThermionEntity entity) async { + Future getWorldTransform({ThermionEntity? entity}) async { + entity ??= this.entity; return double4x4ToMatrix4( TransformManager_getWorldTransform(app.transformManager, entity)); } @@ -709,12 +729,13 @@ class FFIAsset extends ThermionAsset { /// /// /// - Future setTransform(ThermionEntity entity, Matrix4 transform) async { + Future setTransform(Matrix4 transform, {ThermionEntity? entity}) async { + entity ??= this.entity; TransformManager_setTransform( app.transformManager, entity, matrix4ToDouble4x4(transform)); } - /// + /// /// /// Future updateBoneMatrices(ThermionEntity entity) async { @@ -731,24 +752,23 @@ class FFIAsset extends ThermionAsset { /// /// /// - Future getInverseBindMatrix(FFIAsset asset, int boneIndex, + Future getInverseBindMatrix(int boneIndex, {int skinIndex = 0}) async { var matrix = Float32List(16); AnimationManager_getInverseBindMatrix( - animationManager, asset.asset, skinIndex, boneIndex, matrix.address); + animationManager, asset, skinIndex, boneIndex, matrix.address); return Matrix4.fromList(matrix); } /// /// /// - Future getBone(FFIAsset asset, int boneIndex, - {int skinIndex = 0}) async { + Future getBone(int boneIndex, {int skinIndex = 0}) async { if (skinIndex != 0) { throw UnimplementedError("TOOD"); } return AnimationManager_getBone( - animationManager, asset.asset, skinIndex, boneIndex); + animationManager, asset, skinIndex, boneIndex); } /// @@ -781,22 +801,21 @@ class FFIAsset extends ThermionAsset { /// /// @override - Future resetBones(covariant FFIAsset asset) async { - AnimationManager_resetToRestPose(animationManager, asset.asset); + Future resetBones() async { + AnimationManager_resetToRestPose(animationManager, asset); } - /// /// /// @override - Future playAnimation(covariant FFIAsset asset, int index, + Future playAnimation(int index, {bool loop = false, bool reverse = false, bool replaceActive = true, double crossfade = 0.0, double startOffset = 0.0}) async { - AnimationManager_playAnimation(animationManager, asset.asset, index, loop, + AnimationManager_playAnimation(animationManager, asset, index, loop, reverse, replaceActive, crossfade, startOffset); } @@ -804,34 +823,33 @@ class FFIAsset extends ThermionAsset { /// /// @override - Future stopAnimation(FFIAsset asset, int animationIndex) async { - AnimationManager_stopAnimation( - animationManager, asset.asset, animationIndex); + Future stopAnimation(int animationIndex) async { + AnimationManager_stopAnimation(animationManager, asset, animationIndex); } /// /// /// @override - Future stopAnimationByName(FFIAsset asset, String name) async { - var animations = await getAnimationNames(asset); - await stopAnimation(asset, animations.indexOf(name)); + Future stopAnimationByName(String name) async { + var animations = await getAnimationNames(); + await stopAnimation(animations.indexOf(name)); } /// /// /// @override - Future playAnimationByName(FFIAsset asset, String name, + Future playAnimationByName(String name, {bool loop = false, bool reverse = false, bool replaceActive = true, double crossfade = 0.0, bool wait = false}) async { - var animations = await getAnimationNames(asset); + var animations = await getAnimationNames(); var index = animations.indexOf(name); - var duration = await getAnimationDuration(asset, index); - await playAnimation(asset, index, + var duration = await getAnimationDuration(index); + await playAnimation(index, loop: loop, reverse: reverse, replaceActive: replaceActive, @@ -845,13 +863,12 @@ class FFIAsset extends ThermionAsset { /// /// @override - Future setGltfAnimationFrame( - FFIAsset asset, int index, int animationFrame) async { + Future setGltfAnimationFrame(int index, int animationFrame) async { AnimationManager_setGltfAnimationFrame( - animationManager, asset.asset, index, animationFrame); + animationManager, asset, index, animationFrame); } - /// + /// /// /// @override @@ -865,5 +882,4 @@ class FFIAsset extends ThermionAsset { Future removeAnimationComponent(ThermionEntity entity) async { AnimationManager_removeAnimationComponent(animationManager, entity); } - } diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/ffi_filament_app.dart b/thermion_dart/lib/src/viewer/src/ffi/src/ffi_filament_app.dart index e367d92c..23299d85 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/ffi_filament_app.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/ffi_filament_app.dart @@ -2,12 +2,12 @@ import 'dart:async'; import 'dart:typed_data'; import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart'; -import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_asset.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_material.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_render_target.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_swapchain.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_texture.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_view.dart'; +import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_viewer_ffi.dart'; import 'package:thermion_dart/thermion_dart.dart'; typedef RenderCallback = Pointer)>>; @@ -59,7 +59,7 @@ class FFIFilamentApp extends FilamentApp { if (FilamentApp.instance != null) { await FilamentApp.instance!.destroy(); } - + RenderLoop_destroy(); RenderLoop_create(); @@ -102,7 +102,6 @@ class FFIFilamentApp extends FilamentApp { ubershaderMaterialProvider, renderTicker, nameComponentManager); - } final _views = >{}; @@ -170,6 +169,9 @@ class FFIFilamentApp extends FilamentApp { }); } + /// + /// + /// @override Future destroy() async { for (final swapChain in _views.keys) { @@ -177,6 +179,12 @@ class FFIFilamentApp extends FilamentApp { await setRenderable(view, false); } } + for (final swapChain in _views.keys) { + await destroySwapChain(swapChain); + } + RenderLoop_destroy(); + RenderTicker_destroy(renderTicker); + Engine_destroy(engine); } /// @@ -205,7 +213,7 @@ class FFIFilamentApp extends FilamentApp { var bitmask = flags.fold(0, (a, b) => a | b.index); final texturePtr = await withPointerCallback((cb) { Texture_buildRenderThread( - engine!, + engine, width, height, depth, @@ -225,6 +233,9 @@ class FFIFilamentApp extends FilamentApp { ); } + /// + /// + /// Future createTextureSampler( {TextureMinFilter minFilter = TextureMinFilter.LINEAR, TextureMagFilter magFilter = TextureMagFilter.LINEAR, @@ -397,49 +408,6 @@ class FFIFilamentApp extends FilamentApp { return _gridMaterial!; } - /// - /// - /// - @override - Future createGeometry(Geometry geometry, - {List? materialInstances, - bool keepData = false}) async { - var assetPtr = await withPointerCallback((callback) { - var ptrList = Int64List(materialInstances?.length ?? 0); - if (materialInstances != null && materialInstances.isNotEmpty) { - ptrList.setRange( - 0, - materialInstances.length, - materialInstances - .cast() - .map((mi) => mi.pointer.address) - .toList()); - } - - return SceneAsset_createGeometryRenderThread( - engine, - geometry.vertices.address, - geometry.vertices.length, - geometry.normals.address, - geometry.normals.length, - geometry.uvs.address, - geometry.uvs.length, - geometry.indices.address, - geometry.indices.length, - geometry.primitiveType.index, - ptrList.address.cast>(), - ptrList.length, - callback); - }); - if (assetPtr == nullptr) { - throw Exception("Failed to create geometry"); - } - - var asset = FFIAsset(assetPtr, this); - - return asset; - } - /// /// /// @@ -460,6 +428,9 @@ class FFIFilamentApp extends FilamentApp { RenderTicker_renderRenderThread(renderTicker, 0); } + /// + /// + /// @override Future register( covariant FFISwapChain swapChain, covariant FFIView view) async { @@ -468,6 +439,9 @@ class FFIFilamentApp extends FilamentApp { final _hooks = []; + /// + /// + /// @override Future registerRequestFrameHook(Future Function() hook) async { if (!_hooks.contains(hook)) { @@ -475,6 +449,9 @@ class FFIFilamentApp extends FilamentApp { } } + /// + /// + /// @override Future unregisterRequestFrameHook(Future Function() hook) async { if (_hooks.contains(hook)) { @@ -504,4 +481,61 @@ class FFIFilamentApp extends FilamentApp { print("WARNING - render call timed out"); } } + + /// + /// + /// + @override + Future setParent(ThermionEntity child, ThermionEntity? parent, + {bool preserveScaling = false}) async { + TransformManager_setParent(transformManager, child, + parent ?? FILAMENT_ENTITY_NULL, preserveScaling); + } + + /// + /// + /// + @override + Future getParent(ThermionEntity child) async { + var parent = TransformManager_getParent(transformManager, child); + if (parent == FILAMENT_ASSET_ERROR) { + return null; + } + return parent; + } + + /// + /// + /// + @override + Future getAncestor(ThermionEntity child) async { + var parent = TransformManager_getAncestor(transformManager, child); + if (parent == FILAMENT_ASSET_ERROR) { + return null; + } + return parent; + } + + /// + /// + /// + @override + String? getNameForEntity(ThermionEntity entity) { + final result = NameComponentManager_getName(nameComponentManager, entity); + if (result == nullptr) { + return null; + } + return result.cast().toDartString(); + } + + Material? _imageMaterial; + + @override + Future createImageMaterialInstance() async { + _imageMaterial ??= FFIMaterial(Material_createImageMaterial(), + FilamentApp.instance! as FFIFilamentApp); + var instance = + await _imageMaterial!.createInstance() as FFIMaterialInstance; + return instance; + } } diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/ffi_gizmo.dart b/thermion_dart/lib/src/viewer/src/ffi/src/ffi_gizmo.dart index 9e2cd50b..32c23821 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/ffi_gizmo.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/ffi_gizmo.dart @@ -6,13 +6,12 @@ import 'package:thermion_dart/thermion_dart.dart'; import 'ffi_view.dart'; class FFIGizmo extends FFIAsset implements GizmoAsset { - - final Set gizmoEntities; + final Set entities; late NativeCallable _nativeCallback; void Function(GizmoPickResultType axis, Vector3 coords)? _callback; - late FFIView _view; + late FFIView view; void _onPickResult(int resultType, double x, double y, double z) { _callback?.call(GizmoPickResultType.values[resultType], Vector3(x, y, z)); @@ -23,13 +22,16 @@ class FFIGizmo extends FFIAsset implements GizmoAsset { // return SceneManager_isGridEntity(sceneManager, entity); } - bool isGizmoEntity(ThermionEntity entity) => gizmoEntities.contains(entity); + bool isGizmoEntity(ThermionEntity entity) => entities.contains(entity); - FFIGizmo( - this._view, - super.pointer, - super.app, - this.gizmoEntities) { + FFIGizmo( + super.asset, + super.app, + super.animationManager, + { + required this.view, + required this.entities, + }) { _nativeCallback = NativeCallable.listener(_onPickResult); } @@ -53,7 +55,7 @@ class FFIGizmo extends FFIAsset implements GizmoAsset { {Future Function(GizmoPickResultType result, Vector3 coords)? handler}) async { _callback = handler; - final viewport = await _view.getViewport(); + final viewport = await view.getViewport(); y = viewport.height - y; Gizmo_pick(asset.cast(), x, y, _nativeCallback.nativeFunction); diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/ffi_scene.dart b/thermion_dart/lib/src/viewer/src/ffi/src/ffi_scene.dart index 46a3609b..1a831f0e 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/ffi_scene.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/ffi_scene.dart @@ -1,17 +1,11 @@ import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_asset.dart'; -import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart'; -import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_render_target.dart'; import 'package:thermion_dart/src/filament/src/scene.dart'; import 'callbacks.dart'; - class FFIScene extends Scene { final Pointer scene; - final FFIFilamentApp app; - FFIRenderTarget? renderTarget; - - FFIScene(this.scene, this.app) {} + FFIScene(this.scene); @override Future add(covariant FFIAsset asset) async { diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/ffi_view.dart b/thermion_dart/lib/src/viewer/src/ffi/src/ffi_view.dart index b16e20b9..ea1c5287 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/ffi_view.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/ffi_view.dart @@ -1,3 +1,4 @@ +import 'package:thermion_dart/src/filament/src/scene.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_render_target.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_scene.dart'; @@ -113,4 +114,10 @@ class FFIView extends View { Future setLayerVisibility(VisibilityLayers layer, bool visible) async { View_setLayerEnabled(view, layer.value, visible); } + + @override + Future getScene() async { + final ptr = View_getScene(view); + return FFIScene(ptr); + } } diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/grid_overlay.dart b/thermion_dart/lib/src/viewer/src/ffi/src/grid_overlay.dart index 051d39cd..b7484202 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/grid_overlay.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/grid_overlay.dart @@ -3,11 +3,12 @@ import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_asset.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart'; class GridOverlay extends FFIAsset { - GridOverlay(super.asset, super.app); + + GridOverlay(super.asset, super.app, super.animationManager); - static Future create(FFIFilamentApp app) async { + static Future create(FFIFilamentApp app, Pointer animationManager) async { final gridMaterial = await app.gridMaterial; final asset = SceneAsset_createGrid(app.engine, gridMaterial.pointer); - return GridOverlay(asset, app); + return GridOverlay(asset, app, animationManager); } } diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart b/thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart index eea0a5ea..ac69a5e2 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart @@ -1443,6 +1443,11 @@ external ffi.Pointer RenderTicker_create( ffi.Pointer tRenderer, ); +@ffi.Native)>(isLeaf: true) +external void RenderTicker_destroy( + ffi.Pointer tRenderTicker, +); + @ffi.Native< ffi.Void Function(ffi.Pointer, ffi.Pointer)>(isLeaf: true) @@ -2958,6 +2963,11 @@ ffi.Pointer Engine_create( disableHandleUseAfterFreeCheck, ); +@ffi.Native Function(ffi.Pointer)>(isLeaf: true) +external ffi.Pointer Engine_destroy( + ffi.Pointer tEngine, +); + @ffi.Native Function(ffi.Pointer)>(isLeaf: true) external ffi.Pointer Engine_createRenderer( ffi.Pointer tEngine, @@ -3521,6 +3531,15 @@ external void AnimationManager_setGltfAnimationFrame( int frame, ); +@ffi.Native< + ffi.Pointer Function(LoadFilamentResourceFromOwner, + FreeFilamentResourceFromOwner, ffi.Pointer)>(isLeaf: true) +external ffi.Pointer make_resource_loader( + LoadFilamentResourceFromOwner loadFn, + FreeFilamentResourceFromOwner freeFn, + ffi.Pointer owner, +); + final class TCamera extends ffi.Opaque {} final class TEngine extends ffi.Opaque {} @@ -4575,6 +4594,55 @@ enum TBackend { }; } +final class ResourceBuffer extends ffi.Struct { + external ffi.Pointer data; + + @ffi.Int32() + external int size; + + @ffi.Int32() + external int id; +} + +final class ResourceLoaderWrapper extends ffi.Struct { + external LoadFilamentResource loadResource; + + external FreeFilamentResource freeResource; + + external LoadFilamentResourceFromOwner loadFromOwner; + + external FreeFilamentResourceFromOwner freeFromOwner; + + external ffi.Pointer owner; + + external LoadFilamentResourceIntoOutPointer loadToOut; +} + +typedef LoadFilamentResource + = ffi.Pointer>; +typedef LoadFilamentResourceFunction = ResourceBuffer Function( + ffi.Pointer uri); +typedef FreeFilamentResource + = ffi.Pointer>; +typedef FreeFilamentResourceFunction = ffi.Void Function(ResourceBuffer); +typedef DartFreeFilamentResourceFunction = void Function(ResourceBuffer); +typedef LoadFilamentResourceFromOwner + = ffi.Pointer>; +typedef LoadFilamentResourceFromOwnerFunction = ResourceBuffer Function( + ffi.Pointer, ffi.Pointer); +typedef FreeFilamentResourceFromOwner + = ffi.Pointer>; +typedef FreeFilamentResourceFromOwnerFunction = ffi.Void Function( + ResourceBuffer, ffi.Pointer); +typedef DartFreeFilamentResourceFromOwnerFunction = void Function( + ResourceBuffer, ffi.Pointer); +typedef LoadFilamentResourceIntoOutPointer = ffi + .Pointer>; +typedef LoadFilamentResourceIntoOutPointerFunction = ffi.Void Function( + ffi.Pointer uri, ffi.Pointer out); +typedef DartLoadFilamentResourceIntoOutPointerFunction = void Function( + ffi.Pointer uri, ffi.Pointer out); + const int __bool_true_false_are_defined = 1; const int true1 = 1; diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart b/thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart index 56e5c0b2..9f7f694c 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart @@ -2,19 +2,17 @@ import 'dart:async'; import 'dart:io'; import 'dart:math'; import 'dart:typed_data'; -import 'package:animation_tools_dart/animation_tools_dart.dart'; +import 'package:thermion_dart/src/filament/src/light_options.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/background_image.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_asset.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart'; +import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_material.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_render_target.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_scene.dart'; import 'package:thermion_dart/src/filament/src/layers.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/grid_overlay.dart'; import 'package:thermion_dart/thermion_dart.dart'; -import 'package:vector_math/vector_math_64.dart'; import 'package:vector_math/vector_math_64.dart' as v64; -import '../../../../utils/src/matrix.dart'; -import '../../thermion_viewer_base.dart'; import 'package:logging/logging.dart'; import 'callbacks.dart'; @@ -88,13 +86,15 @@ class ThermionViewerFFI extends ThermionViewer { await withPointerCallback( (cb) => Engine_createViewRenderThread(app.engine, cb)), app); - scene = FFIScene(Engine_createScene(app.engine), app); + scene = FFIScene(Engine_createScene(app.engine)); await view.setScene(scene); final camera = FFICamera( await withPointerCallback( (cb) => Engine_createCameraRenderThread(app.engine, cb)), app); _cameras.add(camera); + + await view.setCamera(camera); if (renderTarget != null) { await view.setRenderTarget(renderTarget); } @@ -193,7 +193,7 @@ class ThermionViewerFFI extends ThermionViewer { @override Future setBackgroundImage(String path, {bool fillHeight = false}) async { final imageData = await loadAsset(path); - _backgroundImage = await BackgroundImage.create(app, scene, imageData); + _backgroundImage = await BackgroundImage.create(this, scene, imageData); } /// @@ -406,7 +406,7 @@ class ThermionViewerFFI extends ThermionViewer { throw Exception("An error occurred loading the asset"); } - var thermionAsset = FFIAsset(asset, app); + var thermionAsset = FFIAsset(asset, app, animationManager); _assets.add(thermionAsset); @@ -550,19 +550,6 @@ class ThermionViewerFFI extends ThermionViewer { app.lightManager, lightEntity, direction.x, direction.y, direction.z); } - /// - /// - /// - @override - String? getNameForEntity(ThermionEntity entity) { - final result = - NameComponentManager_getName(app.nameComponentManager, entity); - if (result == nullptr) { - return null; - } - return result.cast().toDartString(); - } - void _onPickResult(int requestId, ThermionEntity entityId, double depth, double fragX, double fragY, double fragZ) async { if (!_pickRequests.containsKey(requestId)) { @@ -611,40 +598,6 @@ class ThermionViewerFFI extends ThermionViewer { }); } - /// - /// - /// - @override - Future setParent(ThermionEntity child, ThermionEntity? parent, - {bool preserveScaling = false}) async { - TransformManager_setParent(app.transformManager, child, - parent ?? FILAMENT_ENTITY_NULL, preserveScaling); - } - - /// - /// - /// - @override - Future getParent(ThermionEntity child) async { - var parent = TransformManager_getParent(app.transformManager, child); - if (parent == FILAMENT_ASSET_ERROR) { - return null; - } - return parent; - } - - /// - /// - /// - @override - Future getAncestor(ThermionEntity child) async { - var parent = TransformManager_getAncestor(app.transformManager, child); - if (parent == FILAMENT_ASSET_ERROR) { - return null; - } - return parent; - } - /// /// /// @@ -678,7 +631,7 @@ class ThermionViewerFFI extends ThermionViewer { /// /// Future showGridOverlay() async { - _grid ??= _grid = await GridOverlay.create(app); + _grid ??= _grid = await GridOverlay.create(app, animationManager); await scene.add(_grid!); await view.setLayerVisibility(VisibilityLayers.OVERLAY, true); } @@ -749,6 +702,52 @@ class ThermionViewerFFI extends ThermionViewer { } } + /// + /// + /// + @override + Future createGeometry(Geometry geometry, + {List? materialInstances, + bool keepData = false}) async { + var assetPtr = await withPointerCallback((callback) { + var ptrList = Int64List(materialInstances?.length ?? 0); + if (materialInstances != null && materialInstances.isNotEmpty) { + ptrList.setRange( + 0, + materialInstances.length, + materialInstances + .cast() + .map((mi) => mi.pointer.address) + .toList()); + } + + return SceneAsset_createGeometryRenderThread( + app.engine, + geometry.vertices.address, + geometry.vertices.length, + geometry.normals.address, + geometry.normals.length, + geometry.uvs.address, + geometry.uvs.length, + geometry.indices.address, + geometry.indices.length, + geometry.primitiveType.index, + ptrList.address.cast>(), + ptrList.length, + callback); + }); + if (assetPtr == nullptr) { + throw Exception("Failed to create geometry"); + } + + var asset = FFIAsset(assetPtr, app, animationManager); + + return asset; + } + + //// + /// + // @override Future createGizmo(FFIView view, GizmoType gizmoType) async { throw UnimplementedError(); diff --git a/thermion_dart/lib/src/viewer/src/thermion_viewer_base.dart b/thermion_dart/lib/src/viewer/src/thermion_viewer_base.dart index a433378e..932f2986 100644 --- a/thermion_dart/lib/src/viewer/src/thermion_viewer_base.dart +++ b/thermion_dart/lib/src/viewer/src/thermion_viewer_base.dart @@ -1,4 +1,5 @@ -import 'package:thermion_dart/src/filament/src/filament_app.dart'; +import 'package:thermion_dart/src/filament/src/light_options.dart'; + import '../../filament/src/shared_types.dart'; import 'dart:typed_data'; import 'package:vector_math/vector_math_64.dart'; @@ -12,10 +13,13 @@ import 'dart:async'; /// Multiple instances can be created; each will correspond /// broadly to a single Filament Scene/View. /// -/// If you know yhat you are doing, you can use a lower level interface by +/// If you know yhat you are doing, you can use a lower level interface by /// using the methods directly via FilamentApp.instance; /// abstract class ThermionViewer { + + Future get initialized; + /// /// /// @@ -142,7 +146,7 @@ abstract class ThermionViewer { bool keepData = false, int priority = 4, int layer = 0, - bool loadResourcesAsync}); + bool loadResourcesAsync = false}); /// /// Load the .gltf asset at the given path, adding all entities to the scene. @@ -225,32 +229,17 @@ abstract class ThermionViewer { /// Future pick(int x, int y, void Function(PickResult) resultHandler); - /// - /// Retrieves the name assigned to the given ThermionEntity (usually corresponds to the glTF mesh name). - /// - String? getNameForEntity(ThermionEntity entity); - - /// - /// Gets the parent entity of [entity]. Returns null if the entity has no parent. - /// - Future getParent(ThermionEntity entity); - - /// - /// Gets the ancestor (ultimate parent) entity of [entity]. Returns null if the entity has no parent. - /// - Future getAncestor(ThermionEntity entity); - - /// - /// Sets the parent transform of [child] to [parent]. - /// - Future setParent(ThermionEntity child, ThermionEntity? parent, - {bool preserveScaling}); - /// /// Sets the draw priority for the given entity. See RenderableManager.h for more details. /// Future setPriority(ThermionEntity entityId, int priority); + /// + /// + /// + Future createGeometry(Geometry geometry, + {List? materialInstances, bool keepData = false}); + /// /// The gizmo for translating/rotating objects. Only one gizmo can be active for a given view. /// diff --git a/thermion_dart/lib/src/viewer/src/thermion_viewer_stub.dart b/thermion_dart/lib/src/viewer/src/thermion_viewer_stub.dart index 9d32fdd6..750ff1a5 100644 --- a/thermion_dart/lib/src/viewer/src/thermion_viewer_stub.dart +++ b/thermion_dart/lib/src/viewer/src/thermion_viewer_stub.dart @@ -1,33 +1,14 @@ import 'dart:typed_data'; - -import 'package:animation_tools_dart/src/bone_animation_data.dart'; -import 'package:animation_tools_dart/src/morph_animation_data.dart'; +import 'package:thermion_dart/src/filament/src/light_options.dart'; import 'package:thermion_dart/thermion_dart.dart'; -import 'package:vector_math/vector_math_64.dart'; class ThermionViewerStub extends ThermionViewer { - @override - Future addAnimationComponent(ThermionEntity entity) { - // TODO: implement addAnimationComponent - throw UnimplementedError(); - } - - @override - Future addBoneAnimation(ThermionAsset asset, BoneAnimationData animation, {int skinIndex = 0, double fadeInInSecs = 0.0, double fadeOutInSecs = 0.0, double maxDelta = 1.0}) { - // TODO: implement addBoneAnimation - throw UnimplementedError(); - } - @override Future addDirectLight(DirectLight light) { // TODO: implement addDirectLight throw UnimplementedError(); } - @override - // TODO: implement app - FilamentApp get app => throw UnimplementedError(); - @override Future clearBackgroundImage() { // TODO: implement clearBackgroundImage @@ -35,14 +16,14 @@ class ThermionViewerStub extends ThermionViewer { } @override - Future clearMorphAnimationData(ThermionEntity entity) { - // TODO: implement clearMorphAnimationData + Future createCamera() { + // TODO: implement createCamera throw UnimplementedError(); } @override - Future createCamera() { - // TODO: implement createCamera + Future createGeometry(Geometry geometry, {List? materialInstances, bool keepData = false}) { + // TODO: implement createGeometry throw UnimplementedError(); } @@ -88,72 +69,12 @@ class ThermionViewerStub extends ThermionViewer { throw UnimplementedError(); } - @override - Future getAncestor(ThermionEntity entity) { - // TODO: implement getAncestor - throw UnimplementedError(); - } - - @override - Future getAnimationDuration(covariant ThermionAsset asset, int animationIndex) { - // TODO: implement getAnimationDuration - throw UnimplementedError(); - } - - @override - Future> getAnimationNames(covariant ThermionAsset asset) { - // TODO: implement getAnimationNames - throw UnimplementedError(); - } - - @override - Future getBone(covariant ThermionAsset asset, int boneIndex, {int skinIndex = 0}) { - // TODO: implement getBone - throw UnimplementedError(); - } - - @override - Future> getBoneNames(covariant ThermionAsset asset, {int skinIndex = 0}) { - // TODO: implement getBoneNames - throw UnimplementedError(); - } - @override int getCameraCount() { // TODO: implement getCameraCount throw UnimplementedError(); } - @override - Future getInverseBindMatrix(covariant ThermionAsset asset, int boneIndex, {int skinIndex = 0}) { - // TODO: implement getInverseBindMatrix - throw UnimplementedError(); - } - - @override - Future getLocalTransform(ThermionEntity entity) { - // TODO: implement getLocalTransform - throw UnimplementedError(); - } - - @override - Future> getMorphTargetNames(covariant ThermionAsset asset, ThermionEntity childEntity) { - // TODO: implement getMorphTargetNames - throw UnimplementedError(); - } - - @override - String? getNameForEntity(ThermionEntity entity) { - // TODO: implement getNameForEntity - throw UnimplementedError(); - } - - @override - Future getParent(ThermionEntity entity) { - // TODO: implement getParent - throw UnimplementedError(); - } - @override Future getRenderableBoundingBox(ThermionEntity entity) { // TODO: implement getRenderableBoundingBox @@ -167,10 +88,8 @@ class ThermionViewerStub extends ThermionViewer { } @override - Future getWorldTransform(ThermionEntity entity) { - // TODO: implement getWorldTransform - throw UnimplementedError(); - } + // TODO: implement initialized + Future get initialized => throw UnimplementedError(); @override Future loadGlb(String path, {int numInstances = 1, bool keepData = false}) { @@ -217,30 +136,6 @@ class ThermionViewerStub extends ThermionViewer { throw UnimplementedError(); } - @override - Future playAnimation(ThermionAsset asset, int index, {bool loop = false, bool reverse = false, bool replaceActive = true, double crossfade = 0.0, double startOffset = 0.0}) { - // TODO: implement playAnimation - throw UnimplementedError(); - } - - @override - Future playAnimationByName(covariant ThermionAsset asset, String name, {bool loop = false, bool reverse = false, bool replaceActive = true, double crossfade = 0.0}) { - // TODO: implement playAnimationByName - throw UnimplementedError(); - } - - @override - Future registerRequestFrameHook(Future Function() hook) { - // TODO: implement registerRequestFrameHook - throw UnimplementedError(); - } - - @override - Future removeAnimationComponent(ThermionEntity entity) { - // TODO: implement removeAnimationComponent - throw UnimplementedError(); - } - @override Future removeGridOverlay() { // TODO: implement removeGridOverlay @@ -275,18 +170,6 @@ class ThermionViewerStub extends ThermionViewer { // TODO: implement rendering bool get rendering => throw UnimplementedError(); - @override - Future requestFrame() { - // TODO: implement requestFrame - throw UnimplementedError(); - } - - @override - Future resetBones(ThermionAsset asset) { - // TODO: implement resetBones - throw UnimplementedError(); - } - @override Future rotateIbl(Matrix3 rotation) { // TODO: implement rotateIbl @@ -329,30 +212,12 @@ class ThermionViewerStub extends ThermionViewer { throw UnimplementedError(); } - @override - Future setBoneTransform(ThermionEntity entity, int boneIndex, Matrix4 transform, {int skinIndex = 0}) { - // TODO: implement setBoneTransform - throw UnimplementedError(); - } - - @override - Future setCamera(ThermionEntity entity, String? name) { - // TODO: implement setCamera - throw UnimplementedError(); - } - @override Future setFrameRate(int framerate) { // TODO: implement setFrameRate throw UnimplementedError(); } - @override - Future setGltfAnimationFrame(covariant ThermionAsset asset, int index, int animationFrame) { - // TODO: implement setGltfAnimationFrame - throw UnimplementedError(); - } - @override Future setLightDirection(ThermionEntity lightEntity, Vector3 direction) { // TODO: implement setLightDirection @@ -365,24 +230,6 @@ class ThermionViewerStub extends ThermionViewer { throw UnimplementedError(); } - @override - Future setMorphAnimationData(covariant ThermionAsset asset, MorphAnimationData animation, {List? targetMeshNames}) { - // TODO: implement setMorphAnimationData - throw UnimplementedError(); - } - - @override - Future setMorphTargetWeights(ThermionEntity entity, List weights) { - // TODO: implement setMorphTargetWeights - throw UnimplementedError(); - } - - @override - Future setParent(ThermionEntity child, ThermionEntity? parent, {bool preserveScaling= false}) { - // TODO: implement setParent - throw UnimplementedError(); - } - @override Future setPostProcessing(bool enabled) { // TODO: implement setPostProcessing @@ -425,12 +272,6 @@ class ThermionViewerStub extends ThermionViewer { throw UnimplementedError(); } - @override - Future setTransform(ThermionEntity entity, Matrix4 transform) { - // TODO: implement setTransform - throw UnimplementedError(); - } - @override Future setViewFrustumCulling(bool enabled) { // TODO: implement setViewFrustumCulling @@ -443,32 +284,8 @@ class ThermionViewerStub extends ThermionViewer { throw UnimplementedError(); } - @override - Future stopAnimation(covariant ThermionAsset asset, int animationIndex) { - // TODO: implement stopAnimation - throw UnimplementedError(); - } - - @override - Future stopAnimationByName(covariant ThermionAsset asset, String name) { - // TODO: implement stopAnimationByName - throw UnimplementedError(); - } - - @override - Future unregisterRequestFrameHook(Future Function() hook) { - // TODO: implement unregisterRequestFrameHook - throw UnimplementedError(); - } - - @override - Future updateBoneMatrices(ThermionEntity entity) { - // TODO: implement updateBoneMatrices - throw UnimplementedError(); - } - @override // TODO: implement view View get view => throw UnimplementedError(); - + }