refactoring
This commit is contained in:
@@ -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<List<ThermionEntity>> getChildEntities();
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<ThermionEntity?> 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<double> 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<List<String>> getMorphTargetNames(
|
||||
covariant ThermionAsset asset, ThermionEntity childEntity);
|
||||
Future<List<String>> 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<List<String>> getBoneNames(covariant ThermionAsset asset,
|
||||
{int skinIndex = 0});
|
||||
Future<List<String>> getBoneNames({int skinIndex = 0});
|
||||
|
||||
///
|
||||
/// Gets the names of all glTF animations embedded in the specified entity.
|
||||
///
|
||||
Future<List<String>> getAnimationNames(covariant ThermionAsset asset);
|
||||
Future<List<String>> getAnimationNames();
|
||||
|
||||
///
|
||||
/// Returns the length (in seconds) of the animation at the given index.
|
||||
///
|
||||
Future<double> getAnimationDuration(
|
||||
covariant ThermionAsset asset, int animationIndex);
|
||||
Future<double> 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<String>? 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<ThermionEntity> getBone(covariant ThermionAsset asset, int boneIndex,
|
||||
{int skinIndex = 0});
|
||||
Future<ThermionEntity> getBone(int boneIndex, {int skinIndex = 0});
|
||||
|
||||
///
|
||||
/// Gets the local (relative to parent) transform for [entity].
|
||||
///
|
||||
Future<Matrix4> getLocalTransform(ThermionEntity entity);
|
||||
Future<Matrix4> getLocalTransform({ThermionEntity? entity});
|
||||
|
||||
///
|
||||
/// Gets the world transform for [entity].
|
||||
///
|
||||
Future<Matrix4> getWorldTransform(ThermionEntity entity);
|
||||
Future<Matrix4> 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<Matrix4> getInverseBindMatrix(
|
||||
covariant ThermionAsset asset, int boneIndex,
|
||||
{int skinIndex = 0});
|
||||
Future<Matrix4> 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<T, U> {
|
||||
}
|
||||
|
||||
abstract class FilamentApp<T> {
|
||||
|
||||
static FilamentApp? instance;
|
||||
|
||||
final T engine;
|
||||
@@ -170,13 +168,6 @@ abstract class FilamentApp<T> {
|
||||
Future<MaterialInstance> getMaterialInstanceAt(
|
||||
ThermionEntity entity, int index);
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future<ThermionAsset> createGeometry(Geometry geometry,
|
||||
{List<MaterialInstance>? materialInstances, bool keepData = false});
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@@ -206,4 +197,27 @@ abstract class FilamentApp<T> {
|
||||
///
|
||||
///
|
||||
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<ThermionEntity?> getParent(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Gets the ancestor (ultimate parent) entity of [entity]. Returns null if the entity has no parent.
|
||||
///
|
||||
Future<ThermionEntity?> getAncestor(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Sets the parent transform of [child] to [parent].
|
||||
///
|
||||
Future setParent(ThermionEntity child, ThermionEntity? parent,
|
||||
{bool preserveScaling});
|
||||
|
||||
Future<MaterialInstance> createImageMaterialInstance();
|
||||
}
|
||||
|
||||
@@ -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<Scene> getScene();
|
||||
Future<Viewport> getViewport();
|
||||
Future setViewport(int width, int height);
|
||||
Future<RenderTarget?> getRenderTarget();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -10,8 +10,7 @@ import '../input_handler.dart';
|
||||
/// point.
|
||||
///
|
||||
class FixedOrbitRotateInputHandlerDelegate implements InputHandlerDelegate {
|
||||
final ThermionViewer viewer;
|
||||
late Future<Camera> _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;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ import '../delegates.dart';
|
||||
import '../input_handler.dart';
|
||||
|
||||
class FreeFlightInputHandlerDelegate implements InputHandlerDelegate {
|
||||
final ThermionViewer viewer;
|
||||
late Future<ThermionEntity> 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<void> 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;
|
||||
|
||||
@@ -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<void>? _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<void>? _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 = <GizmoType, _Gizmo>{};
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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<Axis> 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);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
library;
|
||||
|
||||
export 'src/geometry.dart';
|
||||
export 'src/axis.dart';
|
||||
export 'src/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<BackgroundImage> 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<ThermionAsset> createInstance(
|
||||
{covariant List<MaterialInstance>? materialInstances = null}) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future<List<ThermionEntity>> 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<double> getAnimationDuration(covariant ThermionAsset asset, int animationIndex) {
|
||||
Future<double> getAnimationDuration(int animationIndex) {
|
||||
// TODO: implement getAnimationDuration
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<String>> getAnimationNames(covariant ThermionAsset asset) {
|
||||
Future<List<String>> getAnimationNames() {
|
||||
// TODO: implement getAnimationNames
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ThermionEntity> getBone(covariant ThermionAsset asset, int boneIndex, {int skinIndex = 0}) {
|
||||
Future<ThermionEntity> getBone(int boneIndex, {int skinIndex = 0}) {
|
||||
// TODO: implement getBone
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<String>> getBoneNames(covariant ThermionAsset asset, {int skinIndex = 0}) {
|
||||
Future<List<String>> getBoneNames({int skinIndex = 0}) {
|
||||
// TODO: implement getBoneNames
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Matrix4> getInverseBindMatrix(covariant ThermionAsset asset, int boneIndex, {int skinIndex = 0}) {
|
||||
Future<ThermionEntity?> getChildEntity(String childName) {
|
||||
// TODO: implement getChildEntity
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Matrix4> getInverseBindMatrix(int boneIndex, {int skinIndex = 0}) {
|
||||
// TODO: implement getInverseBindMatrix
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Matrix4> getLocalTransform(ThermionEntity entity) {
|
||||
Future<Matrix4> getLocalTransform({ThermionEntity? entity}) {
|
||||
// TODO: implement getLocalTransform
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<String>> getMorphTargetNames(covariant ThermionAsset asset, ThermionEntity childEntity) {
|
||||
Future<List<String>> getMorphTargetNames({ThermionEntity? entity}) {
|
||||
// TODO: implement getMorphTargetNames
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Matrix4> getWorldTransform(ThermionEntity entity) {
|
||||
Future<Matrix4> 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<String>? targetMeshNames}) {
|
||||
Future setMorphAnimationData(MorphAnimationData animation,
|
||||
{List<String>? 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();
|
||||
}
|
||||
|
||||
@@ -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<TAnimationManager> 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<ThermionEntity?> getChildEntity(
|
||||
FFIAsset asset, String childName) async {
|
||||
Future<ThermionEntity?> 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<ThermionAsset> 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<List<ThermionAsset>> getInstances() async {
|
||||
var count = await getInstanceCount();
|
||||
final result = List<ThermionAsset>.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<List<String>> getMorphTargetNames(
|
||||
covariant FFIAsset asset, ThermionEntity childEntity) async {
|
||||
Future<List<String>> getMorphTargetNames({ThermionEntity? entity}) async {
|
||||
var names = <String>[];
|
||||
|
||||
entity ??= this.entity;
|
||||
|
||||
var count = AnimationManager_getMorphTargetNameCount(
|
||||
animationManager, asset.asset, childEntity);
|
||||
animationManager, asset, entity);
|
||||
var outPtr = allocator<Char>(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<Utf8>().toDartString());
|
||||
}
|
||||
allocator.free(outPtr);
|
||||
return names.cast<String>();
|
||||
}
|
||||
|
||||
Future<List<String>> getBoneNames(covariant FFIAsset asset,
|
||||
{int skinIndex = 0}) async {
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<List<String>> getBoneNames({int skinIndex = 0}) async {
|
||||
var count =
|
||||
AnimationManager_getBoneCount(animationManager, asset.asset, skinIndex);
|
||||
AnimationManager_getBoneCount(animationManager, asset, skinIndex);
|
||||
var out = allocator<Pointer<Char>>(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
out[i] = allocator<Char>(255);
|
||||
}
|
||||
|
||||
AnimationManager_getBoneNames(
|
||||
animationManager, asset.asset, out, skinIndex);
|
||||
AnimationManager_getBoneNames(animationManager, asset, out, skinIndex);
|
||||
var names = <String>[];
|
||||
for (int i = 0; i < count; i++) {
|
||||
var namePtr = out[i];
|
||||
@@ -478,14 +491,13 @@ class FFIAsset extends ThermionAsset {
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future<List<String>> getAnimationNames(covariant FFIAsset asset) async {
|
||||
Future<List<String>> getAnimationNames() async {
|
||||
var animationCount =
|
||||
AnimationManager_getAnimationCount(animationManager, asset.asset);
|
||||
AnimationManager_getAnimationCount(animationManager, asset);
|
||||
var names = <String>[];
|
||||
var outPtr = allocator<Char>(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<Utf8>().toDartString());
|
||||
}
|
||||
allocator.free(outPtr);
|
||||
@@ -497,24 +509,26 @@ class FFIAsset extends ThermionAsset {
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future<double> getAnimationDuration(
|
||||
FFIAsset asset, int animationIndex) async {
|
||||
Future<double> getAnimationDuration(int animationIndex) async {
|
||||
return AnimationManager_getAnimationDuration(
|
||||
animationManager, asset.asset, animationIndex);
|
||||
animationManager, asset, animationIndex);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<double> getAnimationDurationByName(FFIAsset asset, String name) async {
|
||||
var animations = await getAnimationNames(asset);
|
||||
Future<double> 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<String>? 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<Float>(boneNames.length * 16);
|
||||
AnimationManager_getRestLocalTransforms(animationManager, asset.asset,
|
||||
skinIndex, restLocalTransformsRaw, boneNames.length);
|
||||
AnimationManager_getRestLocalTransforms(animationManager, asset, skinIndex,
|
||||
restLocalTransformsRaw, boneNames.length);
|
||||
|
||||
var restLocalTransforms = <Matrix4>[];
|
||||
for (int i = 0; i < boneNames.length; i++) {
|
||||
@@ -630,7 +646,7 @@ class FFIAsset extends ThermionAsset {
|
||||
var data = allocator<Float>(numFrames * 16);
|
||||
|
||||
var bones = await Future.wait(List<Future<ThermionEntity>>.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<Matrix4> getLocalTransform(ThermionEntity entity) async {
|
||||
Future<Matrix4> getLocalTransform({ThermionEntity? entity}) async {
|
||||
entity ??= this.entity;
|
||||
return double4x4ToMatrix4(
|
||||
TransformManager_getLocalTransform(app.transformManager, entity));
|
||||
}
|
||||
@@ -701,7 +720,8 @@ class FFIAsset extends ThermionAsset {
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<Matrix4> getWorldTransform(ThermionEntity entity) async {
|
||||
Future<Matrix4> 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<Matrix4> getInverseBindMatrix(FFIAsset asset, int boneIndex,
|
||||
Future<Matrix4> 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<ThermionEntity> getBone(FFIAsset asset, int boneIndex,
|
||||
{int skinIndex = 0}) async {
|
||||
Future<ThermionEntity> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<NativeFunction<Void Function(Pointer<Void>)>>;
|
||||
@@ -59,7 +59,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
if (FilamentApp.instance != null) {
|
||||
await FilamentApp.instance!.destroy();
|
||||
}
|
||||
|
||||
|
||||
RenderLoop_destroy();
|
||||
RenderLoop_create();
|
||||
|
||||
@@ -102,7 +102,6 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
ubershaderMaterialProvider,
|
||||
renderTicker,
|
||||
nameComponentManager);
|
||||
|
||||
}
|
||||
|
||||
final _views = <FFISwapChain, List<FFIView>>{};
|
||||
@@ -170,6 +169,9 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
});
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future destroy() async {
|
||||
for (final swapChain in _views.keys) {
|
||||
@@ -177,6 +179,12 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
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<Pointer> {
|
||||
var bitmask = flags.fold(0, (a, b) => a | b.index);
|
||||
final texturePtr = await withPointerCallback<TTexture>((cb) {
|
||||
Texture_buildRenderThread(
|
||||
engine!,
|
||||
engine,
|
||||
width,
|
||||
height,
|
||||
depth,
|
||||
@@ -225,6 +233,9 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<TextureSampler> createTextureSampler(
|
||||
{TextureMinFilter minFilter = TextureMinFilter.LINEAR,
|
||||
TextureMagFilter magFilter = TextureMagFilter.LINEAR,
|
||||
@@ -397,49 +408,6 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
return _gridMaterial!;
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future<ThermionAsset> createGeometry(Geometry geometry,
|
||||
{List<MaterialInstance>? materialInstances,
|
||||
bool keepData = false}) async {
|
||||
var assetPtr = await withPointerCallback<TSceneAsset>((callback) {
|
||||
var ptrList = Int64List(materialInstances?.length ?? 0);
|
||||
if (materialInstances != null && materialInstances.isNotEmpty) {
|
||||
ptrList.setRange(
|
||||
0,
|
||||
materialInstances.length,
|
||||
materialInstances
|
||||
.cast<FFIMaterialInstance>()
|
||||
.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<Pointer<TMaterialInstance>>(),
|
||||
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<Pointer> {
|
||||
RenderTicker_renderRenderThread(renderTicker, 0);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future register(
|
||||
covariant FFISwapChain swapChain, covariant FFIView view) async {
|
||||
@@ -468,6 +439,9 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
|
||||
final _hooks = <Future Function()>[];
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future registerRequestFrameHook(Future Function() hook) async {
|
||||
if (!_hooks.contains(hook)) {
|
||||
@@ -475,6 +449,9 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future unregisterRequestFrameHook(Future Function() hook) async {
|
||||
if (_hooks.contains(hook)) {
|
||||
@@ -504,4 +481,61 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
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<ThermionEntity?> getParent(ThermionEntity child) async {
|
||||
var parent = TransformManager_getParent(transformManager, child);
|
||||
if (parent == FILAMENT_ASSET_ERROR) {
|
||||
return null;
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future<ThermionEntity?> 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<Utf8>().toDartString();
|
||||
}
|
||||
|
||||
Material? _imageMaterial;
|
||||
|
||||
@override
|
||||
Future<MaterialInstance> createImageMaterialInstance() async {
|
||||
_imageMaterial ??= FFIMaterial(Material_createImageMaterial(),
|
||||
FilamentApp.instance! as FFIFilamentApp);
|
||||
var instance =
|
||||
await _imageMaterial!.createInstance() as FFIMaterialInstance;
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,13 +6,12 @@ import 'package:thermion_dart/thermion_dart.dart';
|
||||
import 'ffi_view.dart';
|
||||
|
||||
class FFIGizmo extends FFIAsset implements GizmoAsset {
|
||||
|
||||
final Set<ThermionEntity> gizmoEntities;
|
||||
final Set<ThermionEntity> entities;
|
||||
late NativeCallable<GizmoPickCallbackFunction> _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<GizmoPickCallbackFunction>.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<TGizmo>(), x, y, _nativeCallback.nativeFunction);
|
||||
|
||||
@@ -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<TScene> scene;
|
||||
final FFIFilamentApp app;
|
||||
|
||||
FFIRenderTarget? renderTarget;
|
||||
|
||||
FFIScene(this.scene, this.app) {}
|
||||
FFIScene(this.scene);
|
||||
|
||||
@override
|
||||
Future add(covariant FFIAsset asset) async {
|
||||
|
||||
@@ -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<Scene> getScene() async {
|
||||
final ptr = View_getScene(view);
|
||||
return FFIScene(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<GridOverlay> create(FFIFilamentApp app) async {
|
||||
static Future<GridOverlay> create(FFIFilamentApp app, Pointer<TAnimationManager> animationManager) async {
|
||||
final gridMaterial = await app.gridMaterial;
|
||||
final asset = SceneAsset_createGrid(app.engine, gridMaterial.pointer);
|
||||
return GridOverlay(asset, app);
|
||||
return GridOverlay(asset, app, animationManager);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1443,6 +1443,11 @@ external ffi.Pointer<TRenderTicker> RenderTicker_create(
|
||||
ffi.Pointer<TRenderer> tRenderer,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TRenderTicker>)>(isLeaf: true)
|
||||
external void RenderTicker_destroy(
|
||||
ffi.Pointer<TRenderTicker> tRenderTicker,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(ffi.Pointer<TRenderTicker>,
|
||||
ffi.Pointer<TAnimationManager>)>(isLeaf: true)
|
||||
@@ -2958,6 +2963,11 @@ ffi.Pointer<TEngine> Engine_create(
|
||||
disableHandleUseAfterFreeCheck,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Pointer<TEngine> Function(ffi.Pointer<TEngine>)>(isLeaf: true)
|
||||
external ffi.Pointer<TEngine> Engine_destroy(
|
||||
ffi.Pointer<TEngine> tEngine,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Pointer<TRenderer> Function(ffi.Pointer<TEngine>)>(isLeaf: true)
|
||||
external ffi.Pointer<TRenderer> Engine_createRenderer(
|
||||
ffi.Pointer<TEngine> tEngine,
|
||||
@@ -3521,6 +3531,15 @@ external void AnimationManager_setGltfAnimationFrame(
|
||||
int frame,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Pointer<ffi.Void> Function(LoadFilamentResourceFromOwner,
|
||||
FreeFilamentResourceFromOwner, ffi.Pointer<ffi.Void>)>(isLeaf: true)
|
||||
external ffi.Pointer<ffi.Void> make_resource_loader(
|
||||
LoadFilamentResourceFromOwner loadFn,
|
||||
FreeFilamentResourceFromOwner freeFn,
|
||||
ffi.Pointer<ffi.Void> 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<ffi.Void> 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<ffi.Void> owner;
|
||||
|
||||
external LoadFilamentResourceIntoOutPointer loadToOut;
|
||||
}
|
||||
|
||||
typedef LoadFilamentResource
|
||||
= ffi.Pointer<ffi.NativeFunction<LoadFilamentResourceFunction>>;
|
||||
typedef LoadFilamentResourceFunction = ResourceBuffer Function(
|
||||
ffi.Pointer<ffi.Char> uri);
|
||||
typedef FreeFilamentResource
|
||||
= ffi.Pointer<ffi.NativeFunction<FreeFilamentResourceFunction>>;
|
||||
typedef FreeFilamentResourceFunction = ffi.Void Function(ResourceBuffer);
|
||||
typedef DartFreeFilamentResourceFunction = void Function(ResourceBuffer);
|
||||
typedef LoadFilamentResourceFromOwner
|
||||
= ffi.Pointer<ffi.NativeFunction<LoadFilamentResourceFromOwnerFunction>>;
|
||||
typedef LoadFilamentResourceFromOwnerFunction = ResourceBuffer Function(
|
||||
ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Void>);
|
||||
typedef FreeFilamentResourceFromOwner
|
||||
= ffi.Pointer<ffi.NativeFunction<FreeFilamentResourceFromOwnerFunction>>;
|
||||
typedef FreeFilamentResourceFromOwnerFunction = ffi.Void Function(
|
||||
ResourceBuffer, ffi.Pointer<ffi.Void>);
|
||||
typedef DartFreeFilamentResourceFromOwnerFunction = void Function(
|
||||
ResourceBuffer, ffi.Pointer<ffi.Void>);
|
||||
typedef LoadFilamentResourceIntoOutPointer = ffi
|
||||
.Pointer<ffi.NativeFunction<LoadFilamentResourceIntoOutPointerFunction>>;
|
||||
typedef LoadFilamentResourceIntoOutPointerFunction = ffi.Void Function(
|
||||
ffi.Pointer<ffi.Char> uri, ffi.Pointer<ResourceBuffer> out);
|
||||
typedef DartLoadFilamentResourceIntoOutPointerFunction = void Function(
|
||||
ffi.Pointer<ffi.Char> uri, ffi.Pointer<ResourceBuffer> out);
|
||||
|
||||
const int __bool_true_false_are_defined = 1;
|
||||
|
||||
const int true1 = 1;
|
||||
|
||||
@@ -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<TView>(
|
||||
(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<TCamera>(
|
||||
(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<Utf8>().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<ThermionEntity?> getParent(ThermionEntity child) async {
|
||||
var parent = TransformManager_getParent(app.transformManager, child);
|
||||
if (parent == FILAMENT_ASSET_ERROR) {
|
||||
return null;
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future<ThermionEntity?> 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<ThermionAsset> createGeometry(Geometry geometry,
|
||||
{List<MaterialInstance>? materialInstances,
|
||||
bool keepData = false}) async {
|
||||
var assetPtr = await withPointerCallback<TSceneAsset>((callback) {
|
||||
var ptrList = Int64List(materialInstances?.length ?? 0);
|
||||
if (materialInstances != null && materialInstances.isNotEmpty) {
|
||||
ptrList.setRange(
|
||||
0,
|
||||
materialInstances.length,
|
||||
materialInstances
|
||||
.cast<FFIMaterialInstance>()
|
||||
.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<Pointer<TMaterialInstance>>(),
|
||||
ptrList.length,
|
||||
callback);
|
||||
});
|
||||
if (assetPtr == nullptr) {
|
||||
throw Exception("Failed to create geometry");
|
||||
}
|
||||
|
||||
var asset = FFIAsset(assetPtr, app, animationManager);
|
||||
|
||||
return asset;
|
||||
}
|
||||
|
||||
////
|
||||
///
|
||||
//
|
||||
@override
|
||||
Future<GizmoAsset> createGizmo(FFIView view, GizmoType gizmoType) async {
|
||||
throw UnimplementedError();
|
||||
|
||||
@@ -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<bool> 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<ThermionEntity?> getParent(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Gets the ancestor (ultimate parent) entity of [entity]. Returns null if the entity has no parent.
|
||||
///
|
||||
Future<ThermionEntity?> 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<ThermionAsset> createGeometry(Geometry geometry,
|
||||
{List<MaterialInstance>? materialInstances, bool keepData = false});
|
||||
|
||||
///
|
||||
/// The gizmo for translating/rotating objects. Only one gizmo can be active for a given view.
|
||||
///
|
||||
|
||||
@@ -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<ThermionEntity> 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<Camera> createCamera() {
|
||||
// TODO: implement createCamera
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Camera> createCamera() {
|
||||
// TODO: implement createCamera
|
||||
Future<ThermionAsset> createGeometry(Geometry geometry, {List<MaterialInstance>? materialInstances, bool keepData = false}) {
|
||||
// TODO: implement createGeometry
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@@ -88,72 +69,12 @@ class ThermionViewerStub extends ThermionViewer {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ThermionEntity?> getAncestor(ThermionEntity entity) {
|
||||
// TODO: implement getAncestor
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<double> getAnimationDuration(covariant ThermionAsset asset, int animationIndex) {
|
||||
// TODO: implement getAnimationDuration
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<String>> getAnimationNames(covariant ThermionAsset asset) {
|
||||
// TODO: implement getAnimationNames
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ThermionEntity> getBone(covariant ThermionAsset asset, int boneIndex, {int skinIndex = 0}) {
|
||||
// TODO: implement getBone
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<String>> getBoneNames(covariant ThermionAsset asset, {int skinIndex = 0}) {
|
||||
// TODO: implement getBoneNames
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
int getCameraCount() {
|
||||
// TODO: implement getCameraCount
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Matrix4> getInverseBindMatrix(covariant ThermionAsset asset, int boneIndex, {int skinIndex = 0}) {
|
||||
// TODO: implement getInverseBindMatrix
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Matrix4> getLocalTransform(ThermionEntity entity) {
|
||||
// TODO: implement getLocalTransform
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<String>> getMorphTargetNames(covariant ThermionAsset asset, ThermionEntity childEntity) {
|
||||
// TODO: implement getMorphTargetNames
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
String? getNameForEntity(ThermionEntity entity) {
|
||||
// TODO: implement getNameForEntity
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ThermionEntity?> getParent(ThermionEntity entity) {
|
||||
// TODO: implement getParent
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Aabb3> getRenderableBoundingBox(ThermionEntity entity) {
|
||||
// TODO: implement getRenderableBoundingBox
|
||||
@@ -167,10 +88,8 @@ class ThermionViewerStub extends ThermionViewer {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Matrix4> getWorldTransform(ThermionEntity entity) {
|
||||
// TODO: implement getWorldTransform
|
||||
throw UnimplementedError();
|
||||
}
|
||||
// TODO: implement initialized
|
||||
Future<bool> get initialized => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
Future<ThermionAsset> 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<String>? targetMeshNames}) {
|
||||
// TODO: implement setMorphAnimationData
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setMorphTargetWeights(ThermionEntity entity, List<double> 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();
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user