refactoring
This commit is contained in:
@@ -3,17 +3,27 @@ library;
|
|||||||
import 'package:animation_tools_dart/animation_tools_dart.dart';
|
import 'package:animation_tools_dart/animation_tools_dart.dart';
|
||||||
import 'package:thermion_dart/src/filament/src/layers.dart';
|
import 'package:thermion_dart/src/filament/src/layers.dart';
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
import 'package:vector_math/vector_math_64.dart';
|
|
||||||
import 'entity.dart';
|
|
||||||
|
|
||||||
export 'geometry.dart';
|
export 'geometry.dart';
|
||||||
export 'gltf.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 {
|
abstract class ThermionAsset {
|
||||||
///
|
///
|
||||||
///
|
/// The top-most entity in the hierarchy. If this is a glTF asset
|
||||||
///
|
///
|
||||||
ThermionEntity get entity;
|
ThermionEntity get entity;
|
||||||
|
|
||||||
@@ -22,6 +32,11 @@ abstract class ThermionAsset {
|
|||||||
///
|
///
|
||||||
Future<List<ThermionEntity>> getChildEntities();
|
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.
|
/// 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 loop = false,
|
||||||
bool reverse = false,
|
bool reverse = false,
|
||||||
bool replaceActive = true,
|
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.
|
/// 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 loop = false,
|
||||||
bool reverse = false,
|
bool reverse = false,
|
||||||
bool replaceActive = true,
|
bool replaceActive = true,
|
||||||
@@ -114,20 +129,19 @@ abstract class ThermionAsset {
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
Future setGltfAnimationFrame(
|
Future setGltfAnimationFrame(int index, int animationFrame);
|
||||||
covariant ThermionAsset asset, 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].
|
/// 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).
|
/// 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).
|
/// 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);
|
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(
|
Future<List<String>> getMorphTargetNames({ThermionEntity? entity});
|
||||||
covariant ThermionAsset asset, ThermionEntity childEntity);
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// 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,
|
Future<List<String>> getBoneNames({int skinIndex = 0});
|
||||||
{int skinIndex = 0});
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Gets the names of all glTF animations embedded in the specified entity.
|
/// 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.
|
/// Returns the length (in seconds) of the animation at the given index.
|
||||||
///
|
///
|
||||||
Future<double> getAnimationDuration(
|
Future<double> getAnimationDuration(int animationIndex);
|
||||||
covariant ThermionAsset asset, int animationIndex);
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Construct animation(s) for every entity under [asset]. If [targetMeshNames] is provided, only entities with matching names will be animated.
|
/// 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.
|
/// 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.
|
/// It is permissible for [animation] to omit any targets that do exist under [meshName]; these simply won't be animated.
|
||||||
///
|
///
|
||||||
Future setMorphAnimationData(
|
Future setMorphAnimationData(MorphAnimationData animation,
|
||||||
covariant ThermionAsset asset, MorphAnimationData animation,
|
|
||||||
{List<String>? targetMeshNames});
|
{List<String>? targetMeshNames});
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -179,7 +189,7 @@ abstract class ThermionAsset {
|
|||||||
/// Resets all bones in the given entity to their rest pose.
|
/// Resets all bones in the given entity to their rest pose.
|
||||||
/// This should be done before every call to addBoneAnimation.
|
/// 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).
|
/// 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].
|
/// This will be applied in reverse after [fadeOutInSecs].
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
Future addBoneAnimation(ThermionAsset asset, BoneAnimationData animation,
|
Future addBoneAnimation(BoneAnimationData animation,
|
||||||
{int skinIndex = 0,
|
{int skinIndex = 0,
|
||||||
double fadeInInSecs = 0.0,
|
double fadeInInSecs = 0.0,
|
||||||
double fadeOutInSecs = 0.0,
|
double fadeOutInSecs = 0.0,
|
||||||
@@ -209,32 +219,29 @@ abstract class ThermionAsset {
|
|||||||
/// Gets the entity representing the bone at [boneIndex]/[skinIndex].
|
/// Gets the entity representing the bone at [boneIndex]/[skinIndex].
|
||||||
/// The returned entity is only intended for use with [getWorldTransform].
|
/// The returned entity is only intended for use with [getWorldTransform].
|
||||||
///
|
///
|
||||||
Future<ThermionEntity> getBone(covariant ThermionAsset asset, int boneIndex,
|
Future<ThermionEntity> getBone(int boneIndex, {int skinIndex = 0});
|
||||||
{int skinIndex = 0});
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Gets the local (relative to parent) transform for [entity].
|
/// 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].
|
/// 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.
|
/// 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).
|
/// 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.
|
/// This is because all joint information is internally stored with the parent entity.
|
||||||
///
|
///
|
||||||
Future<Matrix4> getInverseBindMatrix(
|
Future<Matrix4> getInverseBindMatrix(int boneIndex, {int skinIndex = 0});
|
||||||
covariant ThermionAsset asset, int boneIndex,
|
|
||||||
{int skinIndex = 0});
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Sets the transform (relative to its parent) for [entity].
|
/// 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
|
/// Updates the bone matrices for [entity] (which must be the ThermionEntity
|
||||||
@@ -264,4 +271,3 @@ abstract class ThermionAsset {
|
|||||||
///
|
///
|
||||||
Future removeAnimationComponent(ThermionEntity entity);
|
Future removeAnimationComponent(ThermionEntity entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:thermion_dart/src/filament/src/engine.dart';
|
import 'package:thermion_dart/src/filament/src/engine.dart';
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
|
|
||||||
@@ -29,7 +28,6 @@ class FilamentConfig<T, U> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract class FilamentApp<T> {
|
abstract class FilamentApp<T> {
|
||||||
|
|
||||||
static FilamentApp? instance;
|
static FilamentApp? instance;
|
||||||
|
|
||||||
final T engine;
|
final T engine;
|
||||||
@@ -170,13 +168,6 @@ abstract class FilamentApp<T> {
|
|||||||
Future<MaterialInstance> getMaterialInstanceAt(
|
Future<MaterialInstance> getMaterialInstanceAt(
|
||||||
ThermionEntity entity, int index);
|
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);
|
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/layers.dart';
|
||||||
|
import 'package:thermion_dart/src/filament/src/scene.dart';
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -18,6 +19,7 @@ class Viewport {
|
|||||||
enum QualityLevel { LOW, MEDIUM, HIGH, ULTRA }
|
enum QualityLevel { LOW, MEDIUM, HIGH, ULTRA }
|
||||||
|
|
||||||
abstract class View {
|
abstract class View {
|
||||||
|
Future<Scene> getScene();
|
||||||
Future<Viewport> getViewport();
|
Future<Viewport> getViewport();
|
||||||
Future setViewport(int width, int height);
|
Future setViewport(int width, int height);
|
||||||
Future<RenderTarget?> getRenderTarget();
|
Future<RenderTarget?> getRenderTarget();
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:thermion_dart/thermion_dart.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/fixed_orbit_camera_rotation_delegate.dart';
|
||||||
import 'implementations/free_flight_camera_delegate.dart';
|
import 'implementations/free_flight_camera_delegate.dart';
|
||||||
|
|
||||||
@@ -64,7 +62,7 @@ class DelegateInputHandler implements InputHandler {
|
|||||||
_inputDeltas[gestureType] = Vector3.zero();
|
_inputDeltas[gestureType] = Vector3.zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
viewer.registerRequestFrameHook(process);
|
FilamentApp.instance!.registerRequestFrameHook(process);
|
||||||
}
|
}
|
||||||
|
|
||||||
factory DelegateInputHandler.fixedOrbit(ThermionViewer viewer,
|
factory DelegateInputHandler.fixedOrbit(ThermionViewer viewer,
|
||||||
@@ -75,7 +73,7 @@ class DelegateInputHandler implements InputHandler {
|
|||||||
DelegateInputHandler(
|
DelegateInputHandler(
|
||||||
viewer: viewer,
|
viewer: viewer,
|
||||||
pickDelegate: pickDelegate,
|
pickDelegate: pickDelegate,
|
||||||
transformDelegate: FixedOrbitRotateInputHandlerDelegate(viewer,
|
transformDelegate: FixedOrbitRotateInputHandlerDelegate(viewer.view,
|
||||||
minimumDistance: minimumDistance),
|
minimumDistance: minimumDistance),
|
||||||
actions: {
|
actions: {
|
||||||
InputType.MMB_HOLD_AND_MOVE: InputAction.ROTATE,
|
InputType.MMB_HOLD_AND_MOVE: InputAction.ROTATE,
|
||||||
@@ -96,9 +94,8 @@ class DelegateInputHandler implements InputHandler {
|
|||||||
DelegateInputHandler(
|
DelegateInputHandler(
|
||||||
viewer: viewer,
|
viewer: viewer,
|
||||||
pickDelegate: pickDelegate,
|
pickDelegate: pickDelegate,
|
||||||
transformDelegate: FreeFlightInputHandlerDelegate(viewer,
|
transformDelegate: FreeFlightInputHandlerDelegate(viewer.view,
|
||||||
clampY: clampY,
|
clampY: clampY,
|
||||||
entity: entity,
|
|
||||||
rotationSensitivity: rotateSensitivity,
|
rotationSensitivity: rotateSensitivity,
|
||||||
zoomSensitivity: zoomSensitivity,
|
zoomSensitivity: zoomSensitivity,
|
||||||
panSensitivity: panSensitivity,
|
panSensitivity: panSensitivity,
|
||||||
@@ -245,7 +242,7 @@ class DelegateInputHandler implements InputHandler {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future dispose() async {
|
Future dispose() async {
|
||||||
viewer.unregisterRequestFrameHook(process);
|
FilamentApp.instance!.unregisterRequestFrameHook(process);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ import '../input_handler.dart';
|
|||||||
/// point.
|
/// point.
|
||||||
///
|
///
|
||||||
class FixedOrbitRotateInputHandlerDelegate implements InputHandlerDelegate {
|
class FixedOrbitRotateInputHandlerDelegate implements InputHandlerDelegate {
|
||||||
final ThermionViewer viewer;
|
final View view;
|
||||||
late Future<Camera> _camera;
|
|
||||||
final double minimumDistance;
|
final double minimumDistance;
|
||||||
late final Vector3 target;
|
late final Vector3 target;
|
||||||
|
|
||||||
@@ -24,20 +23,17 @@ class FixedOrbitRotateInputHandlerDelegate implements InputHandlerDelegate {
|
|||||||
Timer? _updateTimer;
|
Timer? _updateTimer;
|
||||||
|
|
||||||
FixedOrbitRotateInputHandlerDelegate(
|
FixedOrbitRotateInputHandlerDelegate(
|
||||||
this.viewer, {
|
this.view, {
|
||||||
Vector3? target,
|
Vector3? target,
|
||||||
this.minimumDistance = 10.0,
|
this.minimumDistance = 10.0,
|
||||||
this.rotationSensitivity = 0.01,
|
this.rotationSensitivity = 0.01,
|
||||||
this.zoomSensitivity = 0.1,
|
this.zoomSensitivity = 0.1,
|
||||||
}) {
|
}) {
|
||||||
this.target = target ?? Vector3.zero();
|
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);
|
view.getCamera().then((camera) {
|
||||||
return cam;
|
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;
|
_executing = true;
|
||||||
|
|
||||||
final view = await viewer.getViewAt(0);
|
final camera = await view.getCamera();
|
||||||
|
|
||||||
final viewport = await view.getViewport();
|
final viewport = await view.getViewport();
|
||||||
|
|
||||||
var viewMatrix = await viewer.getCameraViewMatrix();
|
var viewMatrix = await camera.getViewMatrix();
|
||||||
var modelMatrix = await viewer.getCameraModelMatrix();
|
var modelMatrix = await camera.getModelMatrix();
|
||||||
var projectionMatrix = await viewer.getCameraProjectionMatrix();
|
var projectionMatrix = await camera.getProjectionMatrix();
|
||||||
var inverseProjectionMatrix = projectionMatrix.clone()..invert();
|
var inverseProjectionMatrix = projectionMatrix.clone()..invert();
|
||||||
Vector3 currentPosition = modelMatrix.getTranslation();
|
Vector3 currentPosition = modelMatrix.getTranslation();
|
||||||
|
|
||||||
@@ -117,14 +114,14 @@ class FixedOrbitRotateInputHandlerDelegate implements InputHandlerDelegate {
|
|||||||
Matrix4 newViewMatrix = makeViewMatrix(currentPosition, target, up);
|
Matrix4 newViewMatrix = makeViewMatrix(currentPosition, target, up);
|
||||||
newViewMatrix.invert();
|
newViewMatrix.invert();
|
||||||
|
|
||||||
await (await _camera).setModelMatrix(newViewMatrix);
|
await camera.setModelMatrix(newViewMatrix);
|
||||||
updatedModelMatrix = newViewMatrix;
|
updatedModelMatrix = newViewMatrix;
|
||||||
}
|
}
|
||||||
} else if (_queuedRotationDelta.length != 0) {
|
} else if (_queuedRotationDelta.length != 0) {
|
||||||
double rotateX = _queuedRotationDelta.x * rotationSensitivity;
|
double rotateX = _queuedRotationDelta.x * rotationSensitivity;
|
||||||
double rotateY = _queuedRotationDelta.y * 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
|
// for simplicity, we always assume a fixed coordinate system where
|
||||||
// we are rotating around world Y and camera X
|
// we are rotating around world Y and camera X
|
||||||
@@ -136,7 +133,7 @@ class FixedOrbitRotateInputHandlerDelegate implements InputHandlerDelegate {
|
|||||||
.asRotationMatrix());
|
.asRotationMatrix());
|
||||||
|
|
||||||
modelMatrix = rot1 * rot2 * modelMatrix;
|
modelMatrix = rot1 * rot2 * modelMatrix;
|
||||||
await (await _camera).setModelMatrix(modelMatrix);
|
await camera.setModelMatrix(modelMatrix);
|
||||||
updatedModelMatrix = modelMatrix;
|
updatedModelMatrix = modelMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import '../delegates.dart';
|
|||||||
import '../input_handler.dart';
|
import '../input_handler.dart';
|
||||||
|
|
||||||
class FreeFlightInputHandlerDelegate implements InputHandlerDelegate {
|
class FreeFlightInputHandlerDelegate implements InputHandlerDelegate {
|
||||||
final ThermionViewer viewer;
|
final View view;
|
||||||
late Future<ThermionEntity> entity;
|
|
||||||
final Vector3? minBounds;
|
final Vector3? minBounds;
|
||||||
final Vector3? maxBounds;
|
final Vector3? maxBounds;
|
||||||
final double rotationSensitivity;
|
final double rotationSensitivity;
|
||||||
@@ -20,21 +20,14 @@ class FreeFlightInputHandlerDelegate implements InputHandlerDelegate {
|
|||||||
double _queuedZoomDelta = 0.0;
|
double _queuedZoomDelta = 0.0;
|
||||||
Vector3 _queuedMoveDelta = Vector3.zero();
|
Vector3 _queuedMoveDelta = Vector3.zero();
|
||||||
|
|
||||||
FreeFlightInputHandlerDelegate(this.viewer,
|
FreeFlightInputHandlerDelegate(this.view,
|
||||||
{this.minBounds,
|
{this.minBounds,
|
||||||
this.maxBounds,
|
this.maxBounds,
|
||||||
this.rotationSensitivity = 0.001,
|
this.rotationSensitivity = 0.001,
|
||||||
this.movementSensitivity = 0.1,
|
this.movementSensitivity = 0.1,
|
||||||
this.zoomSensitivity = 0.1,
|
this.zoomSensitivity = 0.1,
|
||||||
this.panSensitivity = 0.1,
|
this.panSensitivity = 0.1,
|
||||||
this.clampY,
|
this.clampY}) {}
|
||||||
ThermionEntity? entity}) {
|
|
||||||
if (entity != null) {
|
|
||||||
this.entity = Future.value(entity);
|
|
||||||
} else {
|
|
||||||
this.entity = viewer.getMainCameraEntity();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> queue(InputAction action, Vector3? delta) async {
|
Future<void> queue(InputAction action, Vector3? delta) async {
|
||||||
@@ -76,9 +69,9 @@ class FreeFlightInputHandlerDelegate implements InputHandlerDelegate {
|
|||||||
return null;
|
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();
|
Vector3 relativeTranslation = Vector3.zero();
|
||||||
Quaternion relativeRotation = Quaternion.identity();
|
Quaternion relativeRotation = Quaternion.identity();
|
||||||
@@ -121,17 +114,18 @@ class FreeFlightInputHandlerDelegate implements InputHandlerDelegate {
|
|||||||
_queuedMoveDelta = Vector3.zero();
|
_queuedMoveDelta = Vector3.zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the managed entity is not the active camera, we need to apply the rotation from the current camera model matrix
|
// // 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
|
// // to the entity's translation
|
||||||
if (await entity != activeCamera.getEntity()) {
|
// if (await entity != activeCamera.getEntity()) {
|
||||||
Matrix4 modelMatrix = await activeCamera.getModelMatrix();
|
// Matrix4 modelMatrix = await activeCamera.getModelMatrix();
|
||||||
relativeTranslation = modelMatrix.getRotation() * relativeTranslation;
|
// relativeTranslation = modelMatrix.getRotation() * relativeTranslation;
|
||||||
}
|
// }
|
||||||
|
|
||||||
var updated = Matrix4.compose(
|
var updated = Matrix4.compose(
|
||||||
relativeTranslation, relativeRotation, Vector3(1, 1, 1)) *
|
relativeTranslation, relativeRotation, Vector3(1, 1, 1)) *
|
||||||
current;
|
current;
|
||||||
await viewer.setTransform(await entity, updated);
|
|
||||||
|
await activeCamera.setModelMatrix(updated);
|
||||||
|
|
||||||
_executing = false;
|
_executing = false;
|
||||||
return updated;
|
return updated;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
import 'package:vector_math/vector_math_64.dart';
|
|
||||||
|
|
||||||
class _Gizmo {
|
class _Gizmo {
|
||||||
final ThermionViewer viewer;
|
final ThermionViewer viewer;
|
||||||
@@ -16,7 +15,7 @@ class _Gizmo {
|
|||||||
_Gizmo(this._gizmo, this.viewer, this.type);
|
_Gizmo(this._gizmo, this.viewer, this.type);
|
||||||
|
|
||||||
static Future<_Gizmo> forType(ThermionViewer viewer, GizmoType type) async {
|
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);
|
return _Gizmo(await viewer.createGizmo(view, type), viewer, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,12 +25,14 @@ class _Gizmo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future hide() async {
|
Future hide() async {
|
||||||
await _gizmo.removeFromScene();
|
final scene = await viewer.view.getScene();
|
||||||
|
await scene.remove(_gizmo);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future reveal() async {
|
Future reveal() async {
|
||||||
await _gizmo.addToScene();
|
final scene = await viewer.view.getScene();
|
||||||
gizmoTransform = await viewer.getWorldTransform(_gizmo.entity);
|
await scene.add(_gizmo);
|
||||||
|
gizmoTransform = await _gizmo.getWorldTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
double _getAngleBetweenVectors(Vector2 v1, Vector2 v2) {
|
double _getAngleBetweenVectors(Vector2 v1, Vector2 v2) {
|
||||||
@@ -76,17 +77,17 @@ class _Gizmo {
|
|||||||
await _updateRotation(currentPosition, delta);
|
await _updateRotation(currentPosition, delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
await viewer.setTransform(_gizmo.entity, gizmoTransform!);
|
await _gizmo.setTransform(gizmoTransform!);
|
||||||
|
|
||||||
transformUpdates.add((transform: gizmoTransform!));
|
transformUpdates.add((transform: gizmoTransform!));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void>? _updateTranslation(
|
Future<void>? _updateTranslation(
|
||||||
Vector2 currentPosition, Vector2 delta) async {
|
Vector2 currentPosition, Vector2 delta) async {
|
||||||
var view = await viewer.getViewAt(0);
|
var view = await viewer.view;
|
||||||
var camera = await viewer.getActiveCamera();
|
var camera = await viewer.getActiveCamera();
|
||||||
var viewport = await view.getViewport();
|
var viewport = await view.getViewport();
|
||||||
var projectionMatrix = await viewer.getCameraProjectionMatrix();
|
var projectionMatrix = await camera.getProjectionMatrix();
|
||||||
var viewMatrix = await camera.getViewMatrix();
|
var viewMatrix = await camera.getViewMatrix();
|
||||||
var inverseViewMatrix = await camera.getModelMatrix();
|
var inverseViewMatrix = await camera.getModelMatrix();
|
||||||
var inverseProjectionMatrix = projectionMatrix.clone()..invert();
|
var inverseProjectionMatrix = projectionMatrix.clone()..invert();
|
||||||
@@ -121,10 +122,9 @@ class _Gizmo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void>? _updateRotation(Vector2 currentPosition, Vector2 delta) async {
|
Future<void>? _updateRotation(Vector2 currentPosition, Vector2 delta) async {
|
||||||
var view = await viewer.getViewAt(0);
|
var camera = await viewer.view.getCamera();
|
||||||
var camera = await viewer.getActiveCamera();
|
var viewport = await viewer.view.getViewport();
|
||||||
var viewport = await view.getViewport();
|
var projectionMatrix = await camera.getProjectionMatrix();
|
||||||
var projectionMatrix = await viewer.getCameraProjectionMatrix();
|
|
||||||
var viewMatrix = await camera.getViewMatrix();
|
var viewMatrix = await camera.getViewMatrix();
|
||||||
|
|
||||||
// Get gizmo center in screen space
|
// Get gizmo center in screen space
|
||||||
@@ -187,7 +187,6 @@ class _Gizmo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class GizmoInputHandler extends InputHandler {
|
class GizmoInputHandler extends InputHandler {
|
||||||
|
|
||||||
final ThermionViewer viewer;
|
final ThermionViewer viewer;
|
||||||
|
|
||||||
late final _gizmos = <GizmoType, _Gizmo>{};
|
late final _gizmos = <GizmoType, _Gizmo>{};
|
||||||
@@ -202,7 +201,7 @@ class GizmoInputHandler extends InputHandler {
|
|||||||
}
|
}
|
||||||
_attached = entity;
|
_attached = entity;
|
||||||
if (_active != null) {
|
if (_active != null) {
|
||||||
await viewer.setParent(_attached!, _active!._gizmo.entity);
|
await FilamentApp.instance!.setParent(_attached!, _active!._gizmo.entity);
|
||||||
await _active!.reveal();
|
await _active!.reveal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -215,7 +214,7 @@ class GizmoInputHandler extends InputHandler {
|
|||||||
if (_attached == null) {
|
if (_attached == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await viewer.setParent(_attached!, 0);
|
await FilamentApp.instance!.setParent(_attached!, null);
|
||||||
await _active?.hide();
|
await _active?.hide();
|
||||||
_attached = null;
|
_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;
|
library;
|
||||||
|
|
||||||
export 'src/geometry.dart';
|
export 'src/geometry.dart';
|
||||||
export 'src/axis.dart';
|
|
||||||
export 'src/image.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/filament/src/layers.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.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_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_scene.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_texture.dart';
|
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_texture.dart';
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
|
|
||||||
class BackgroundImage extends ThermionAsset {
|
class BackgroundImage extends ThermionAsset {
|
||||||
final ThermionAsset asset;
|
final ThermionAsset asset;
|
||||||
|
|
||||||
ThermionEntity get entity => asset.entity;
|
ThermionEntity get entity => asset.entity;
|
||||||
|
|
||||||
Texture? _backgroundImageTexture;
|
Texture? _backgroundImageTexture;
|
||||||
FFIMaterial? _imageMaterial;
|
|
||||||
FFITextureSampler? _imageSampler;
|
FFITextureSampler? _imageSampler;
|
||||||
|
|
||||||
final FFIScene scene;
|
final FFIScene scene;
|
||||||
final FilamentApp app;
|
|
||||||
|
|
||||||
BackgroundImage._(this.asset, this.scene, this.app,
|
BackgroundImage._(
|
||||||
this._backgroundImageTexture, this._imageMaterial, this._imageSampler);
|
this.asset, this.scene, this._backgroundImageTexture, this._imageSampler);
|
||||||
|
|
||||||
Future destroy() async {
|
Future destroy() async {
|
||||||
Scene_removeEntity(scene.scene, entity);
|
Scene_removeEntity(scene.scene, entity);
|
||||||
@@ -32,33 +30,39 @@ class BackgroundImage extends ThermionAsset {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Future<BackgroundImage> create(
|
static Future<BackgroundImage> create(
|
||||||
FFIFilamentApp app, FFIScene scene, Uint8List imageData) async {
|
ThermionViewer viewer, FFIScene scene, Uint8List imageData) async {
|
||||||
final image = await app.decodeImage(imageData);
|
final image = await FilamentApp.instance!.decodeImage(imageData);
|
||||||
var backgroundImageTexture = await app.createTexture(
|
var backgroundImageTexture = await FilamentApp.instance!
|
||||||
await image.getWidth(), await image.getHeight());
|
.createTexture(await image.getWidth(), await image.getHeight());
|
||||||
var imageMaterial = FFIMaterial(Material_createImageMaterial(), app);
|
|
||||||
var imageSampler = await app.createTextureSampler() as FFITextureSampler;
|
var imageSampler =
|
||||||
|
await FilamentApp.instance!.createTextureSampler() as FFITextureSampler;
|
||||||
|
|
||||||
var imageMaterialInstance =
|
var imageMaterialInstance =
|
||||||
await imageMaterial!.createInstance() as FFIMaterialInstance;
|
await FilamentApp.instance!.createImageMaterialInstance();
|
||||||
|
|
||||||
await imageMaterialInstance.setParameterTexture(
|
await imageMaterialInstance.setParameterTexture(
|
||||||
"image",
|
"image", backgroundImageTexture as FFITexture, imageSampler);
|
||||||
backgroundImageTexture as FFITexture,
|
|
||||||
imageSampler as FFITextureSampler);
|
|
||||||
var backgroundImage =
|
var backgroundImage =
|
||||||
await app.createGeometry(GeometryHelper.fullscreenQuad()) as FFIAsset;
|
await viewer.createGeometry(GeometryHelper.fullscreenQuad());
|
||||||
backgroundImage.setMaterialInstanceAt(imageMaterialInstance);
|
backgroundImage.setMaterialInstanceAt(imageMaterialInstance);
|
||||||
await scene.add(backgroundImage);
|
await scene.add(backgroundImage as FFIAsset);
|
||||||
return BackgroundImage._(backgroundImage, scene, app,
|
return BackgroundImage._(
|
||||||
backgroundImageTexture, imageMaterial, imageSampler);
|
backgroundImage, scene, backgroundImageTexture, imageSampler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
@override
|
@override
|
||||||
Future<ThermionAsset> createInstance(
|
Future<ThermionAsset> createInstance(
|
||||||
{covariant List<MaterialInstance>? materialInstances = null}) {
|
{covariant List<MaterialInstance>? materialInstances = null}) {
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
@override
|
@override
|
||||||
Future<List<ThermionEntity>> getChildEntities() async {
|
Future<List<ThermionEntity>> getChildEntities() async {
|
||||||
return [];
|
return [];
|
||||||
@@ -129,7 +133,11 @@ class BackgroundImage extends ThermionAsset {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@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
|
// TODO: implement addBoneAnimation
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
@@ -141,61 +149,76 @@ class BackgroundImage extends ThermionAsset {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<double> getAnimationDuration(covariant ThermionAsset asset, int animationIndex) {
|
Future<double> getAnimationDuration(int animationIndex) {
|
||||||
// TODO: implement getAnimationDuration
|
// TODO: implement getAnimationDuration
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<String>> getAnimationNames(covariant ThermionAsset asset) {
|
Future<List<String>> getAnimationNames() {
|
||||||
// TODO: implement getAnimationNames
|
// TODO: implement getAnimationNames
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<ThermionEntity> getBone(covariant ThermionAsset asset, int boneIndex, {int skinIndex = 0}) {
|
Future<ThermionEntity> getBone(int boneIndex, {int skinIndex = 0}) {
|
||||||
// TODO: implement getBone
|
// TODO: implement getBone
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<String>> getBoneNames(covariant ThermionAsset asset, {int skinIndex = 0}) {
|
Future<List<String>> getBoneNames({int skinIndex = 0}) {
|
||||||
// TODO: implement getBoneNames
|
// TODO: implement getBoneNames
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@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
|
// TODO: implement getInverseBindMatrix
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Matrix4> getLocalTransform(ThermionEntity entity) {
|
Future<Matrix4> getLocalTransform({ThermionEntity? entity}) {
|
||||||
// TODO: implement getLocalTransform
|
// TODO: implement getLocalTransform
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<String>> getMorphTargetNames(covariant ThermionAsset asset, ThermionEntity childEntity) {
|
Future<List<String>> getMorphTargetNames({ThermionEntity? entity}) {
|
||||||
// TODO: implement getMorphTargetNames
|
// TODO: implement getMorphTargetNames
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Matrix4> getWorldTransform(ThermionEntity entity) {
|
Future<Matrix4> getWorldTransform({ThermionEntity? entity}) {
|
||||||
// TODO: implement getWorldTransform
|
// TODO: implement getWorldTransform
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@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
|
// TODO: implement playAnimation
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@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
|
// TODO: implement playAnimationByName
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
@@ -207,25 +230,28 @@ class BackgroundImage extends ThermionAsset {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future resetBones(ThermionAsset asset) {
|
Future resetBones() {
|
||||||
// TODO: implement resetBones
|
// TODO: implement resetBones
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@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
|
// TODO: implement setBoneTransform
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setGltfAnimationFrame(covariant ThermionAsset asset, int index, int animationFrame) {
|
Future setGltfAnimationFrame(int index, int animationFrame) {
|
||||||
// TODO: implement setGltfAnimationFrame
|
// TODO: implement setGltfAnimationFrame
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setMorphAnimationData(covariant ThermionAsset asset, MorphAnimationData animation, {List<String>? targetMeshNames}) {
|
Future setMorphAnimationData(MorphAnimationData animation,
|
||||||
|
{List<String>? targetMeshNames}) {
|
||||||
// TODO: implement setMorphAnimationData
|
// TODO: implement setMorphAnimationData
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
@@ -243,13 +269,13 @@ class BackgroundImage extends ThermionAsset {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future stopAnimation(covariant ThermionAsset asset, int animationIndex) {
|
Future stopAnimation(int animationIndex) {
|
||||||
// TODO: implement stopAnimation
|
// TODO: implement stopAnimation
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future stopAnimationByName(covariant ThermionAsset asset, String name) {
|
Future stopAnimationByName(String name) {
|
||||||
// TODO: implement stopAnimationByName
|
// TODO: implement stopAnimationByName
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import 'dart:typed_data';
|
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/filament/src/layers.dart';
|
||||||
import 'package:thermion_dart/src/utils/src/matrix.dart';
|
import 'package:thermion_dart/src/utils/src/matrix.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.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/src/viewer/src/ffi/src/thermion_viewer_ffi.dart';
|
||||||
import 'package:thermion_dart/thermion_dart.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' as v64;
|
||||||
import 'package:vector_math/vector_math_64.dart';
|
|
||||||
|
|
||||||
class FFIAsset extends ThermionAsset {
|
class FFIAsset extends ThermionAsset {
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@@ -22,6 +22,11 @@ class FFIAsset extends ThermionAsset {
|
|||||||
///
|
///
|
||||||
final FFIFilamentApp app;
|
final FFIFilamentApp app;
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
|
final Pointer<TAnimationManager> animationManager;
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@@ -37,10 +42,13 @@ class FFIAsset extends ThermionAsset {
|
|||||||
///
|
///
|
||||||
late final ThermionEntity entity;
|
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);
|
entity = SceneAsset_getEntity(asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,8 +67,7 @@ class FFIAsset extends ThermionAsset {
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future<ThermionEntity?> getChildEntity(
|
Future<ThermionEntity?> getChildEntity(String childName) async {
|
||||||
FFIAsset asset, String childName) async {
|
|
||||||
final childEntities = await getChildEntities();
|
final childEntities = await getChildEntities();
|
||||||
for (final entity in childEntities) {
|
for (final entity in childEntities) {
|
||||||
var name = NameComponentManager_getName(app.nameComponentManager, entity);
|
var name = NameComponentManager_getName(app.nameComponentManager, entity);
|
||||||
@@ -71,6 +78,9 @@ class FFIAsset extends ThermionAsset {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
@override
|
@override
|
||||||
Future<ThermionAsset> getInstance(int index) async {
|
Future<ThermionAsset> getInstance(int index) async {
|
||||||
if (isInstance) {
|
if (isInstance) {
|
||||||
@@ -81,7 +91,7 @@ class FFIAsset extends ThermionAsset {
|
|||||||
if (instance == nullptr) {
|
if (instance == nullptr) {
|
||||||
throw Exception("No instance available at index $index");
|
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) {
|
if (created == FILAMENT_ASSET_ERROR) {
|
||||||
throw Exception("Failed to create instance");
|
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 {
|
Future<List<ThermionAsset>> getInstances() async {
|
||||||
var count = await getInstanceCount();
|
var count = await getInstanceCount();
|
||||||
final result = List<ThermionAsset>.generate(count, (i) {
|
final result = List<ThermionAsset>.generate(count, (i) {
|
||||||
return FFIAsset(SceneAsset_getInstance(asset, i), app);
|
return FFIAsset(SceneAsset_getInstance(asset, i), app, animationManager);
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -163,7 +173,7 @@ class FFIAsset extends ThermionAsset {
|
|||||||
var targetEntity = this.entity;
|
var targetEntity = this.entity;
|
||||||
if (entityIndex != null) {
|
if (entityIndex != null) {
|
||||||
final childEntities = await this.getChildEntities();
|
final childEntities = await this.getChildEntities();
|
||||||
targetEntity = childEntities[entityIndex!];
|
targetEntity = childEntities[entityIndex];
|
||||||
}
|
}
|
||||||
var sourceMaterialInstance = FFIMaterialInstance(
|
var sourceMaterialInstance = FFIMaterialInstance(
|
||||||
RenderableManager_getMaterialInstanceAt(
|
RenderableManager_getMaterialInstanceAt(
|
||||||
@@ -209,7 +219,7 @@ class FFIAsset extends ThermionAsset {
|
|||||||
|
|
||||||
if (entityIndex != null) {
|
if (entityIndex != null) {
|
||||||
var highlightChildEntities = await _highlight!.getChildEntities();
|
var highlightChildEntities = await _highlight!.getChildEntities();
|
||||||
targetHighlightEntity = highlightChildEntities[entityIndex!];
|
targetHighlightEntity = highlightChildEntities[entityIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderableManager_setPriority(
|
RenderableManager_setPriority(
|
||||||
@@ -397,7 +407,8 @@ class FFIAsset extends ThermionAsset {
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
Future transformToUnitCube() async {
|
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
|
@override
|
||||||
Future<List<String>> getMorphTargetNames(
|
Future<List<String>> getMorphTargetNames({ThermionEntity? entity}) async {
|
||||||
covariant FFIAsset asset, ThermionEntity childEntity) async {
|
|
||||||
var names = <String>[];
|
var names = <String>[];
|
||||||
|
|
||||||
|
entity ??= this.entity;
|
||||||
|
|
||||||
var count = AnimationManager_getMorphTargetNameCount(
|
var count = AnimationManager_getMorphTargetNameCount(
|
||||||
animationManager, asset.asset, childEntity);
|
animationManager, asset, entity);
|
||||||
var outPtr = allocator<Char>(255);
|
var outPtr = allocator<Char>(255);
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
AnimationManager_getMorphTargetName(
|
AnimationManager_getMorphTargetName(
|
||||||
animationManager, asset.asset, childEntity, outPtr, i);
|
animationManager, asset, entity, outPtr, i);
|
||||||
names.add(outPtr.cast<Utf8>().toDartString());
|
names.add(outPtr.cast<Utf8>().toDartString());
|
||||||
}
|
}
|
||||||
allocator.free(outPtr);
|
allocator.free(outPtr);
|
||||||
return names.cast<String>();
|
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 =
|
var count =
|
||||||
AnimationManager_getBoneCount(animationManager, asset.asset, skinIndex);
|
AnimationManager_getBoneCount(animationManager, asset, skinIndex);
|
||||||
var out = allocator<Pointer<Char>>(count);
|
var out = allocator<Pointer<Char>>(count);
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
out[i] = allocator<Char>(255);
|
out[i] = allocator<Char>(255);
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimationManager_getBoneNames(
|
AnimationManager_getBoneNames(animationManager, asset, out, skinIndex);
|
||||||
animationManager, asset.asset, out, skinIndex);
|
|
||||||
var names = <String>[];
|
var names = <String>[];
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
var namePtr = out[i];
|
var namePtr = out[i];
|
||||||
@@ -478,14 +491,13 @@ class FFIAsset extends ThermionAsset {
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future<List<String>> getAnimationNames(covariant FFIAsset asset) async {
|
Future<List<String>> getAnimationNames() async {
|
||||||
var animationCount =
|
var animationCount =
|
||||||
AnimationManager_getAnimationCount(animationManager, asset.asset);
|
AnimationManager_getAnimationCount(animationManager, asset);
|
||||||
var names = <String>[];
|
var names = <String>[];
|
||||||
var outPtr = allocator<Char>(255);
|
var outPtr = allocator<Char>(255);
|
||||||
for (int i = 0; i < animationCount; i++) {
|
for (int i = 0; i < animationCount; i++) {
|
||||||
AnimationManager_getAnimationName(
|
AnimationManager_getAnimationName(animationManager, asset, outPtr, i);
|
||||||
animationManager, asset.asset, outPtr, i);
|
|
||||||
names.add(outPtr.cast<Utf8>().toDartString());
|
names.add(outPtr.cast<Utf8>().toDartString());
|
||||||
}
|
}
|
||||||
allocator.free(outPtr);
|
allocator.free(outPtr);
|
||||||
@@ -497,24 +509,26 @@ class FFIAsset extends ThermionAsset {
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future<double> getAnimationDuration(
|
Future<double> getAnimationDuration(int animationIndex) async {
|
||||||
FFIAsset asset, int animationIndex) async {
|
|
||||||
return AnimationManager_getAnimationDuration(
|
return AnimationManager_getAnimationDuration(
|
||||||
animationManager, asset.asset, animationIndex);
|
animationManager, asset, animationIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
Future<double> getAnimationDurationByName(FFIAsset asset, String name) async {
|
Future<double> getAnimationDurationByName(String name) async {
|
||||||
var animations = await getAnimationNames(asset);
|
var animations = await getAnimationNames();
|
||||||
var index = animations.indexOf(name);
|
var index = animations.indexOf(name);
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
throw Exception("Failed to find animation $name");
|
throw Exception("Failed to find animation $name");
|
||||||
}
|
}
|
||||||
return getAnimationDuration(asset, index);
|
return getAnimationDuration(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
Future clearMorphAnimationData(ThermionEntity entity) async {
|
Future clearMorphAnimationData(ThermionEntity entity) async {
|
||||||
if (!AnimationManager_clearMorphAnimation(animationManager, entity)) {
|
if (!AnimationManager_clearMorphAnimation(animationManager, entity)) {
|
||||||
throw Exception("Failed to clear morph animation");
|
throw Exception("Failed to clear morph animation");
|
||||||
@@ -525,11 +539,13 @@ class FFIAsset extends ThermionAsset {
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future setMorphAnimationData(FFIAsset asset, MorphAnimationData animation,
|
Future setMorphAnimationData(MorphAnimationData animation,
|
||||||
{List<String>? targetMeshNames}) async {
|
{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) {
|
if (targetMeshNames != null) {
|
||||||
for (final targetMeshName in targetMeshNames) {
|
for (final targetMeshName in targetMeshNames) {
|
||||||
if (!meshNames.contains(targetMeshName)) {
|
if (!meshNames.contains(targetMeshName)) {
|
||||||
@@ -554,7 +570,7 @@ class FFIAsset extends ThermionAsset {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var meshMorphTargets = await getMorphTargetNames(asset, meshEntity);
|
var meshMorphTargets = await getMorphTargetNames(entity: meshEntity);
|
||||||
|
|
||||||
var intersection = animation.morphTargets
|
var intersection = animation.morphTargets
|
||||||
.toSet()
|
.toSet()
|
||||||
@@ -598,7 +614,7 @@ class FFIAsset extends ThermionAsset {
|
|||||||
/// Currently, scale is not supported.
|
/// Currently, scale is not supported.
|
||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future addBoneAnimation(covariant FFIAsset asset, BoneAnimationData animation,
|
Future addBoneAnimation(BoneAnimationData animation,
|
||||||
{int skinIndex = 0,
|
{int skinIndex = 0,
|
||||||
double fadeOutInSecs = 0.0,
|
double fadeOutInSecs = 0.0,
|
||||||
double fadeInInSecs = 0.0,
|
double fadeInInSecs = 0.0,
|
||||||
@@ -610,10 +626,10 @@ class FFIAsset extends ThermionAsset {
|
|||||||
if (skinIndex != 0) {
|
if (skinIndex != 0) {
|
||||||
throw UnimplementedError("TODO - support skinIndex != 0 ");
|
throw UnimplementedError("TODO - support skinIndex != 0 ");
|
||||||
}
|
}
|
||||||
var boneNames = await getBoneNames(asset);
|
var boneNames = await getBoneNames();
|
||||||
var restLocalTransformsRaw = allocator<Float>(boneNames.length * 16);
|
var restLocalTransformsRaw = allocator<Float>(boneNames.length * 16);
|
||||||
AnimationManager_getRestLocalTransforms(animationManager, asset.asset,
|
AnimationManager_getRestLocalTransforms(animationManager, asset, skinIndex,
|
||||||
skinIndex, restLocalTransformsRaw, boneNames.length);
|
restLocalTransformsRaw, boneNames.length);
|
||||||
|
|
||||||
var restLocalTransforms = <Matrix4>[];
|
var restLocalTransforms = <Matrix4>[];
|
||||||
for (int i = 0; i < boneNames.length; i++) {
|
for (int i = 0; i < boneNames.length; i++) {
|
||||||
@@ -630,7 +646,7 @@ class FFIAsset extends ThermionAsset {
|
|||||||
var data = allocator<Float>(numFrames * 16);
|
var data = allocator<Float>(numFrames * 16);
|
||||||
|
|
||||||
var bones = await Future.wait(List<Future<ThermionEntity>>.generate(
|
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++) {
|
for (int i = 0; i < animation.bones.length; i++) {
|
||||||
var boneName = animation.bones[i];
|
var boneName = animation.bones[i];
|
||||||
@@ -645,13 +661,15 @@ class FFIAsset extends ThermionAsset {
|
|||||||
|
|
||||||
var world = Matrix4.identity();
|
var world = Matrix4.identity();
|
||||||
// this odd use of ! is intentional, without it, the WASM optimizer gets in trouble
|
// 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) {
|
while (true) {
|
||||||
if (!bones.contains(parentBoneEntity!)) {
|
if (!bones.contains(parentBoneEntity!)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
world = restLocalTransforms[bones.indexOf(parentBoneEntity!)] * world;
|
world = restLocalTransforms[bones.indexOf(parentBoneEntity!)] * world;
|
||||||
parentBoneEntity = (await getParent(parentBoneEntity))!;
|
parentBoneEntity =
|
||||||
|
(await FilamentApp.instance!.getParent(parentBoneEntity))!;
|
||||||
}
|
}
|
||||||
|
|
||||||
world = Matrix4.identity()..setRotation(world.getRotation());
|
world = Matrix4.identity()..setRotation(world.getRotation());
|
||||||
@@ -677,7 +695,7 @@ class FFIAsset extends ThermionAsset {
|
|||||||
|
|
||||||
AnimationManager_addBoneAnimation(
|
AnimationManager_addBoneAnimation(
|
||||||
animationManager,
|
animationManager,
|
||||||
asset.asset,
|
asset,
|
||||||
skinIndex,
|
skinIndex,
|
||||||
entityBoneIndex,
|
entityBoneIndex,
|
||||||
data,
|
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(
|
return double4x4ToMatrix4(
|
||||||
TransformManager_getLocalTransform(app.transformManager, entity));
|
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(
|
return double4x4ToMatrix4(
|
||||||
TransformManager_getWorldTransform(app.transformManager, entity));
|
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(
|
TransformManager_setTransform(
|
||||||
app.transformManager, entity, matrix4ToDouble4x4(transform));
|
app.transformManager, entity, matrix4ToDouble4x4(transform));
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
Future updateBoneMatrices(ThermionEntity entity) async {
|
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 {
|
{int skinIndex = 0}) async {
|
||||||
var matrix = Float32List(16);
|
var matrix = Float32List(16);
|
||||||
AnimationManager_getInverseBindMatrix(
|
AnimationManager_getInverseBindMatrix(
|
||||||
animationManager, asset.asset, skinIndex, boneIndex, matrix.address);
|
animationManager, asset, skinIndex, boneIndex, matrix.address);
|
||||||
return Matrix4.fromList(matrix);
|
return Matrix4.fromList(matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
Future<ThermionEntity> getBone(FFIAsset asset, int boneIndex,
|
Future<ThermionEntity> getBone(int boneIndex, {int skinIndex = 0}) async {
|
||||||
{int skinIndex = 0}) async {
|
|
||||||
if (skinIndex != 0) {
|
if (skinIndex != 0) {
|
||||||
throw UnimplementedError("TOOD");
|
throw UnimplementedError("TOOD");
|
||||||
}
|
}
|
||||||
return AnimationManager_getBone(
|
return AnimationManager_getBone(
|
||||||
animationManager, asset.asset, skinIndex, boneIndex);
|
animationManager, asset, skinIndex, boneIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -781,22 +801,21 @@ class FFIAsset extends ThermionAsset {
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future resetBones(covariant FFIAsset asset) async {
|
Future resetBones() async {
|
||||||
AnimationManager_resetToRestPose(animationManager, asset.asset);
|
AnimationManager_resetToRestPose(animationManager, asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future playAnimation(covariant FFIAsset asset, int index,
|
Future playAnimation(int index,
|
||||||
{bool loop = false,
|
{bool loop = false,
|
||||||
bool reverse = false,
|
bool reverse = false,
|
||||||
bool replaceActive = true,
|
bool replaceActive = true,
|
||||||
double crossfade = 0.0,
|
double crossfade = 0.0,
|
||||||
double startOffset = 0.0}) async {
|
double startOffset = 0.0}) async {
|
||||||
AnimationManager_playAnimation(animationManager, asset.asset, index, loop,
|
AnimationManager_playAnimation(animationManager, asset, index, loop,
|
||||||
reverse, replaceActive, crossfade, startOffset);
|
reverse, replaceActive, crossfade, startOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -804,34 +823,33 @@ class FFIAsset extends ThermionAsset {
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future stopAnimation(FFIAsset asset, int animationIndex) async {
|
Future stopAnimation(int animationIndex) async {
|
||||||
AnimationManager_stopAnimation(
|
AnimationManager_stopAnimation(animationManager, asset, animationIndex);
|
||||||
animationManager, asset.asset, animationIndex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future stopAnimationByName(FFIAsset asset, String name) async {
|
Future stopAnimationByName(String name) async {
|
||||||
var animations = await getAnimationNames(asset);
|
var animations = await getAnimationNames();
|
||||||
await stopAnimation(asset, animations.indexOf(name));
|
await stopAnimation(animations.indexOf(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future playAnimationByName(FFIAsset asset, String name,
|
Future playAnimationByName(String name,
|
||||||
{bool loop = false,
|
{bool loop = false,
|
||||||
bool reverse = false,
|
bool reverse = false,
|
||||||
bool replaceActive = true,
|
bool replaceActive = true,
|
||||||
double crossfade = 0.0,
|
double crossfade = 0.0,
|
||||||
bool wait = false}) async {
|
bool wait = false}) async {
|
||||||
var animations = await getAnimationNames(asset);
|
var animations = await getAnimationNames();
|
||||||
var index = animations.indexOf(name);
|
var index = animations.indexOf(name);
|
||||||
var duration = await getAnimationDuration(asset, index);
|
var duration = await getAnimationDuration(index);
|
||||||
await playAnimation(asset, index,
|
await playAnimation(index,
|
||||||
loop: loop,
|
loop: loop,
|
||||||
reverse: reverse,
|
reverse: reverse,
|
||||||
replaceActive: replaceActive,
|
replaceActive: replaceActive,
|
||||||
@@ -845,13 +863,12 @@ class FFIAsset extends ThermionAsset {
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future setGltfAnimationFrame(
|
Future setGltfAnimationFrame(int index, int animationFrame) async {
|
||||||
FFIAsset asset, int index, int animationFrame) async {
|
|
||||||
AnimationManager_setGltfAnimationFrame(
|
AnimationManager_setGltfAnimationFrame(
|
||||||
animationManager, asset.asset, index, animationFrame);
|
animationManager, asset, index, animationFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
@@ -865,5 +882,4 @@ class FFIAsset extends ThermionAsset {
|
|||||||
Future removeAnimationComponent(ThermionEntity entity) async {
|
Future removeAnimationComponent(ThermionEntity entity) async {
|
||||||
AnimationManager_removeAnimationComponent(animationManager, entity);
|
AnimationManager_removeAnimationComponent(animationManager, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ import 'dart:async';
|
|||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.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_material.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_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_swapchain.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_texture.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/ffi_view.dart';
|
||||||
|
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_viewer_ffi.dart';
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
|
|
||||||
typedef RenderCallback = Pointer<NativeFunction<Void Function(Pointer<Void>)>>;
|
typedef RenderCallback = Pointer<NativeFunction<Void Function(Pointer<Void>)>>;
|
||||||
@@ -59,7 +59,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
if (FilamentApp.instance != null) {
|
if (FilamentApp.instance != null) {
|
||||||
await FilamentApp.instance!.destroy();
|
await FilamentApp.instance!.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderLoop_destroy();
|
RenderLoop_destroy();
|
||||||
RenderLoop_create();
|
RenderLoop_create();
|
||||||
|
|
||||||
@@ -102,7 +102,6 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
ubershaderMaterialProvider,
|
ubershaderMaterialProvider,
|
||||||
renderTicker,
|
renderTicker,
|
||||||
nameComponentManager);
|
nameComponentManager);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final _views = <FFISwapChain, List<FFIView>>{};
|
final _views = <FFISwapChain, List<FFIView>>{};
|
||||||
@@ -170,6 +169,9 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
@override
|
@override
|
||||||
Future destroy() async {
|
Future destroy() async {
|
||||||
for (final swapChain in _views.keys) {
|
for (final swapChain in _views.keys) {
|
||||||
@@ -177,6 +179,12 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
await setRenderable(view, false);
|
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);
|
var bitmask = flags.fold(0, (a, b) => a | b.index);
|
||||||
final texturePtr = await withPointerCallback<TTexture>((cb) {
|
final texturePtr = await withPointerCallback<TTexture>((cb) {
|
||||||
Texture_buildRenderThread(
|
Texture_buildRenderThread(
|
||||||
engine!,
|
engine,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
depth,
|
depth,
|
||||||
@@ -225,6 +233,9 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
Future<TextureSampler> createTextureSampler(
|
Future<TextureSampler> createTextureSampler(
|
||||||
{TextureMinFilter minFilter = TextureMinFilter.LINEAR,
|
{TextureMinFilter minFilter = TextureMinFilter.LINEAR,
|
||||||
TextureMagFilter magFilter = TextureMagFilter.LINEAR,
|
TextureMagFilter magFilter = TextureMagFilter.LINEAR,
|
||||||
@@ -397,49 +408,6 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
return _gridMaterial!;
|
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);
|
RenderTicker_renderRenderThread(renderTicker, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
@override
|
@override
|
||||||
Future register(
|
Future register(
|
||||||
covariant FFISwapChain swapChain, covariant FFIView view) async {
|
covariant FFISwapChain swapChain, covariant FFIView view) async {
|
||||||
@@ -468,6 +439,9 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
|
|
||||||
final _hooks = <Future Function()>[];
|
final _hooks = <Future Function()>[];
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
@override
|
@override
|
||||||
Future registerRequestFrameHook(Future Function() hook) async {
|
Future registerRequestFrameHook(Future Function() hook) async {
|
||||||
if (!_hooks.contains(hook)) {
|
if (!_hooks.contains(hook)) {
|
||||||
@@ -475,6 +449,9 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
@override
|
@override
|
||||||
Future unregisterRequestFrameHook(Future Function() hook) async {
|
Future unregisterRequestFrameHook(Future Function() hook) async {
|
||||||
if (_hooks.contains(hook)) {
|
if (_hooks.contains(hook)) {
|
||||||
@@ -504,4 +481,61 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
print("WARNING - render call timed out");
|
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';
|
import 'ffi_view.dart';
|
||||||
|
|
||||||
class FFIGizmo extends FFIAsset implements GizmoAsset {
|
class FFIGizmo extends FFIAsset implements GizmoAsset {
|
||||||
|
final Set<ThermionEntity> entities;
|
||||||
final Set<ThermionEntity> gizmoEntities;
|
|
||||||
late NativeCallable<GizmoPickCallbackFunction> _nativeCallback;
|
late NativeCallable<GizmoPickCallbackFunction> _nativeCallback;
|
||||||
|
|
||||||
void Function(GizmoPickResultType axis, Vector3 coords)? _callback;
|
void Function(GizmoPickResultType axis, Vector3 coords)? _callback;
|
||||||
|
|
||||||
late FFIView _view;
|
late FFIView view;
|
||||||
|
|
||||||
void _onPickResult(int resultType, double x, double y, double z) {
|
void _onPickResult(int resultType, double x, double y, double z) {
|
||||||
_callback?.call(GizmoPickResultType.values[resultType], Vector3(x, y, 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);
|
// return SceneManager_isGridEntity(sceneManager, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isGizmoEntity(ThermionEntity entity) => gizmoEntities.contains(entity);
|
bool isGizmoEntity(ThermionEntity entity) => entities.contains(entity);
|
||||||
|
|
||||||
FFIGizmo(
|
FFIGizmo(
|
||||||
this._view,
|
super.asset,
|
||||||
super.pointer,
|
super.app,
|
||||||
super.app,
|
super.animationManager,
|
||||||
this.gizmoEntities) {
|
{
|
||||||
|
required this.view,
|
||||||
|
required this.entities,
|
||||||
|
}) {
|
||||||
_nativeCallback =
|
_nativeCallback =
|
||||||
NativeCallable<GizmoPickCallbackFunction>.listener(_onPickResult);
|
NativeCallable<GizmoPickCallbackFunction>.listener(_onPickResult);
|
||||||
}
|
}
|
||||||
@@ -53,7 +55,7 @@ class FFIGizmo extends FFIAsset implements GizmoAsset {
|
|||||||
{Future Function(GizmoPickResultType result, Vector3 coords)?
|
{Future Function(GizmoPickResultType result, Vector3 coords)?
|
||||||
handler}) async {
|
handler}) async {
|
||||||
_callback = handler;
|
_callback = handler;
|
||||||
final viewport = await _view.getViewport();
|
final viewport = await view.getViewport();
|
||||||
y = viewport.height - y;
|
y = viewport.height - y;
|
||||||
|
|
||||||
Gizmo_pick(asset.cast<TGizmo>(), x, y, _nativeCallback.nativeFunction);
|
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_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 'package:thermion_dart/src/filament/src/scene.dart';
|
||||||
import 'callbacks.dart';
|
import 'callbacks.dart';
|
||||||
|
|
||||||
|
|
||||||
class FFIScene extends Scene {
|
class FFIScene extends Scene {
|
||||||
final Pointer<TScene> scene;
|
final Pointer<TScene> scene;
|
||||||
final FFIFilamentApp app;
|
|
||||||
|
|
||||||
FFIRenderTarget? renderTarget;
|
FFIScene(this.scene);
|
||||||
|
|
||||||
FFIScene(this.scene, this.app) {}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future add(covariant FFIAsset asset) async {
|
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_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_render_target.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_scene.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 {
|
Future setLayerVisibility(VisibilityLayers layer, bool visible) async {
|
||||||
View_setLayerEnabled(view, layer.value, visible);
|
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';
|
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
|
||||||
|
|
||||||
class GridOverlay extends FFIAsset {
|
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 gridMaterial = await app.gridMaterial;
|
||||||
final asset = SceneAsset_createGrid(app.engine, gridMaterial.pointer);
|
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.Pointer<TRenderer> tRenderer,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Void Function(ffi.Pointer<TRenderTicker>)>(isLeaf: true)
|
||||||
|
external void RenderTicker_destroy(
|
||||||
|
ffi.Pointer<TRenderTicker> tRenderTicker,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(ffi.Pointer<TRenderTicker>,
|
ffi.Void Function(ffi.Pointer<TRenderTicker>,
|
||||||
ffi.Pointer<TAnimationManager>)>(isLeaf: true)
|
ffi.Pointer<TAnimationManager>)>(isLeaf: true)
|
||||||
@@ -2958,6 +2963,11 @@ ffi.Pointer<TEngine> Engine_create(
|
|||||||
disableHandleUseAfterFreeCheck,
|
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)
|
@ffi.Native<ffi.Pointer<TRenderer> Function(ffi.Pointer<TEngine>)>(isLeaf: true)
|
||||||
external ffi.Pointer<TRenderer> Engine_createRenderer(
|
external ffi.Pointer<TRenderer> Engine_createRenderer(
|
||||||
ffi.Pointer<TEngine> tEngine,
|
ffi.Pointer<TEngine> tEngine,
|
||||||
@@ -3521,6 +3531,15 @@ external void AnimationManager_setGltfAnimationFrame(
|
|||||||
int frame,
|
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 TCamera extends ffi.Opaque {}
|
||||||
|
|
||||||
final class TEngine 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 __bool_true_false_are_defined = 1;
|
||||||
|
|
||||||
const int true1 = 1;
|
const int true1 = 1;
|
||||||
|
|||||||
@@ -2,19 +2,17 @@ import 'dart:async';
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'dart:typed_data';
|
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/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_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_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_render_target.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_scene.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/filament/src/layers.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/grid_overlay.dart';
|
import 'package:thermion_dart/src/viewer/src/ffi/src/grid_overlay.dart';
|
||||||
import 'package:thermion_dart/thermion_dart.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 '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 'package:logging/logging.dart';
|
||||||
|
|
||||||
import 'callbacks.dart';
|
import 'callbacks.dart';
|
||||||
@@ -88,13 +86,15 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
await withPointerCallback<TView>(
|
await withPointerCallback<TView>(
|
||||||
(cb) => Engine_createViewRenderThread(app.engine, cb)),
|
(cb) => Engine_createViewRenderThread(app.engine, cb)),
|
||||||
app);
|
app);
|
||||||
scene = FFIScene(Engine_createScene(app.engine), app);
|
scene = FFIScene(Engine_createScene(app.engine));
|
||||||
await view.setScene(scene);
|
await view.setScene(scene);
|
||||||
final camera = FFICamera(
|
final camera = FFICamera(
|
||||||
await withPointerCallback<TCamera>(
|
await withPointerCallback<TCamera>(
|
||||||
(cb) => Engine_createCameraRenderThread(app.engine, cb)),
|
(cb) => Engine_createCameraRenderThread(app.engine, cb)),
|
||||||
app);
|
app);
|
||||||
_cameras.add(camera);
|
_cameras.add(camera);
|
||||||
|
|
||||||
|
await view.setCamera(camera);
|
||||||
if (renderTarget != null) {
|
if (renderTarget != null) {
|
||||||
await view.setRenderTarget(renderTarget);
|
await view.setRenderTarget(renderTarget);
|
||||||
}
|
}
|
||||||
@@ -193,7 +193,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
@override
|
@override
|
||||||
Future setBackgroundImage(String path, {bool fillHeight = false}) async {
|
Future setBackgroundImage(String path, {bool fillHeight = false}) async {
|
||||||
final imageData = await loadAsset(path);
|
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");
|
throw Exception("An error occurred loading the asset");
|
||||||
}
|
}
|
||||||
|
|
||||||
var thermionAsset = FFIAsset(asset, app);
|
var thermionAsset = FFIAsset(asset, app, animationManager);
|
||||||
|
|
||||||
_assets.add(thermionAsset);
|
_assets.add(thermionAsset);
|
||||||
|
|
||||||
@@ -550,19 +550,6 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
app.lightManager, lightEntity, direction.x, direction.y, direction.z);
|
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,
|
void _onPickResult(int requestId, ThermionEntity entityId, double depth,
|
||||||
double fragX, double fragY, double fragZ) async {
|
double fragX, double fragY, double fragZ) async {
|
||||||
if (!_pickRequests.containsKey(requestId)) {
|
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 {
|
Future showGridOverlay() async {
|
||||||
_grid ??= _grid = await GridOverlay.create(app);
|
_grid ??= _grid = await GridOverlay.create(app, animationManager);
|
||||||
await scene.add(_grid!);
|
await scene.add(_grid!);
|
||||||
await view.setLayerVisibility(VisibilityLayers.OVERLAY, true);
|
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
|
@override
|
||||||
Future<GizmoAsset> createGizmo(FFIView view, GizmoType gizmoType) async {
|
Future<GizmoAsset> createGizmo(FFIView view, GizmoType gizmoType) async {
|
||||||
throw UnimplementedError();
|
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 '../../filament/src/shared_types.dart';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:vector_math/vector_math_64.dart';
|
import 'package:vector_math/vector_math_64.dart';
|
||||||
@@ -12,10 +13,13 @@ import 'dart:async';
|
|||||||
/// Multiple instances can be created; each will correspond
|
/// Multiple instances can be created; each will correspond
|
||||||
/// broadly to a single Filament Scene/View.
|
/// 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;
|
/// using the methods directly via FilamentApp.instance;
|
||||||
///
|
///
|
||||||
abstract class ThermionViewer {
|
abstract class ThermionViewer {
|
||||||
|
|
||||||
|
Future<bool> get initialized;
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@@ -142,7 +146,7 @@ abstract class ThermionViewer {
|
|||||||
bool keepData = false,
|
bool keepData = false,
|
||||||
int priority = 4,
|
int priority = 4,
|
||||||
int layer = 0,
|
int layer = 0,
|
||||||
bool loadResourcesAsync});
|
bool loadResourcesAsync = false});
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Load the .gltf asset at the given path, adding all entities to the scene.
|
/// 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);
|
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.
|
/// Sets the draw priority for the given entity. See RenderableManager.h for more details.
|
||||||
///
|
///
|
||||||
Future setPriority(ThermionEntity entityId, int priority);
|
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.
|
/// 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 'dart:typed_data';
|
||||||
|
import 'package:thermion_dart/src/filament/src/light_options.dart';
|
||||||
import 'package:animation_tools_dart/src/bone_animation_data.dart';
|
|
||||||
import 'package:animation_tools_dart/src/morph_animation_data.dart';
|
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
import 'package:vector_math/vector_math_64.dart';
|
|
||||||
|
|
||||||
class ThermionViewerStub extends ThermionViewer {
|
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
|
@override
|
||||||
Future<ThermionEntity> addDirectLight(DirectLight light) {
|
Future<ThermionEntity> addDirectLight(DirectLight light) {
|
||||||
// TODO: implement addDirectLight
|
// TODO: implement addDirectLight
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
// TODO: implement app
|
|
||||||
FilamentApp get app => throw UnimplementedError();
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future clearBackgroundImage() {
|
Future clearBackgroundImage() {
|
||||||
// TODO: implement clearBackgroundImage
|
// TODO: implement clearBackgroundImage
|
||||||
@@ -35,14 +16,14 @@ class ThermionViewerStub extends ThermionViewer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future clearMorphAnimationData(ThermionEntity entity) {
|
Future<Camera> createCamera() {
|
||||||
// TODO: implement clearMorphAnimationData
|
// TODO: implement createCamera
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Camera> createCamera() {
|
Future<ThermionAsset> createGeometry(Geometry geometry, {List<MaterialInstance>? materialInstances, bool keepData = false}) {
|
||||||
// TODO: implement createCamera
|
// TODO: implement createGeometry
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,72 +69,12 @@ class ThermionViewerStub extends ThermionViewer {
|
|||||||
throw UnimplementedError();
|
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
|
@override
|
||||||
int getCameraCount() {
|
int getCameraCount() {
|
||||||
// TODO: implement getCameraCount
|
// TODO: implement getCameraCount
|
||||||
throw UnimplementedError();
|
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
|
@override
|
||||||
Future<Aabb3> getRenderableBoundingBox(ThermionEntity entity) {
|
Future<Aabb3> getRenderableBoundingBox(ThermionEntity entity) {
|
||||||
// TODO: implement getRenderableBoundingBox
|
// TODO: implement getRenderableBoundingBox
|
||||||
@@ -167,10 +88,8 @@ class ThermionViewerStub extends ThermionViewer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Matrix4> getWorldTransform(ThermionEntity entity) {
|
// TODO: implement initialized
|
||||||
// TODO: implement getWorldTransform
|
Future<bool> get initialized => throw UnimplementedError();
|
||||||
throw UnimplementedError();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<ThermionAsset> loadGlb(String path, {int numInstances = 1, bool keepData = false}) {
|
Future<ThermionAsset> loadGlb(String path, {int numInstances = 1, bool keepData = false}) {
|
||||||
@@ -217,30 +136,6 @@ class ThermionViewerStub extends ThermionViewer {
|
|||||||
throw UnimplementedError();
|
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
|
@override
|
||||||
Future removeGridOverlay() {
|
Future removeGridOverlay() {
|
||||||
// TODO: implement removeGridOverlay
|
// TODO: implement removeGridOverlay
|
||||||
@@ -275,18 +170,6 @@ class ThermionViewerStub extends ThermionViewer {
|
|||||||
// TODO: implement rendering
|
// TODO: implement rendering
|
||||||
bool get rendering => throw UnimplementedError();
|
bool get rendering => throw UnimplementedError();
|
||||||
|
|
||||||
@override
|
|
||||||
Future requestFrame() {
|
|
||||||
// TODO: implement requestFrame
|
|
||||||
throw UnimplementedError();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future resetBones(ThermionAsset asset) {
|
|
||||||
// TODO: implement resetBones
|
|
||||||
throw UnimplementedError();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future rotateIbl(Matrix3 rotation) {
|
Future rotateIbl(Matrix3 rotation) {
|
||||||
// TODO: implement rotateIbl
|
// TODO: implement rotateIbl
|
||||||
@@ -329,30 +212,12 @@ class ThermionViewerStub extends ThermionViewer {
|
|||||||
throw UnimplementedError();
|
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
|
@override
|
||||||
Future setFrameRate(int framerate) {
|
Future setFrameRate(int framerate) {
|
||||||
// TODO: implement setFrameRate
|
// TODO: implement setFrameRate
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future setGltfAnimationFrame(covariant ThermionAsset asset, int index, int animationFrame) {
|
|
||||||
// TODO: implement setGltfAnimationFrame
|
|
||||||
throw UnimplementedError();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setLightDirection(ThermionEntity lightEntity, Vector3 direction) {
|
Future setLightDirection(ThermionEntity lightEntity, Vector3 direction) {
|
||||||
// TODO: implement setLightDirection
|
// TODO: implement setLightDirection
|
||||||
@@ -365,24 +230,6 @@ class ThermionViewerStub extends ThermionViewer {
|
|||||||
throw UnimplementedError();
|
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
|
@override
|
||||||
Future setPostProcessing(bool enabled) {
|
Future setPostProcessing(bool enabled) {
|
||||||
// TODO: implement setPostProcessing
|
// TODO: implement setPostProcessing
|
||||||
@@ -425,12 +272,6 @@ class ThermionViewerStub extends ThermionViewer {
|
|||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future setTransform(ThermionEntity entity, Matrix4 transform) {
|
|
||||||
// TODO: implement setTransform
|
|
||||||
throw UnimplementedError();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setViewFrustumCulling(bool enabled) {
|
Future setViewFrustumCulling(bool enabled) {
|
||||||
// TODO: implement setViewFrustumCulling
|
// TODO: implement setViewFrustumCulling
|
||||||
@@ -443,32 +284,8 @@ class ThermionViewerStub extends ThermionViewer {
|
|||||||
throw UnimplementedError();
|
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
|
@override
|
||||||
// TODO: implement view
|
// TODO: implement view
|
||||||
View get view => throw UnimplementedError();
|
View get view => throw UnimplementedError();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user