Compare commits
24 Commits
thermion_f
...
thermion_d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
099a895eb6 | ||
|
|
3b810f84da | ||
|
|
10f2c7d36b | ||
|
|
5b849638de | ||
|
|
857fd6f782 | ||
|
|
29edec63ab | ||
|
|
c6afc4756a | ||
|
|
365657cf88 | ||
|
|
5441dedcf4 | ||
|
|
254b6d8af2 | ||
|
|
1459aea5cf | ||
|
|
80d8525671 | ||
|
|
389a165ed3 | ||
|
|
d8f309d21b | ||
|
|
ee983ddfaa | ||
|
|
c1cdd37e9d | ||
|
|
646f05933d | ||
|
|
3f854a7f27 | ||
|
|
740dbea8bd | ||
|
|
95a44936ac | ||
|
|
9deafc7371 | ||
|
|
c1af7e374d | ||
|
|
cd71db72be | ||
|
|
a9d90f966b |
66
CHANGELOG.md
66
CHANGELOG.md
@@ -3,6 +3,72 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## 2024-10-10
|
||||
|
||||
### Changes
|
||||
|
||||
---
|
||||
|
||||
Packages with breaking changes:
|
||||
|
||||
- There are no breaking changes in this release.
|
||||
|
||||
Packages with other changes:
|
||||
|
||||
- [`thermion_dart` - `v0.2.1-dev.0.0.5`](#thermion_dart---v021-dev005)
|
||||
- [`thermion_flutter_platform_interface` - `v0.2.1-dev.4`](#thermion_flutter_platform_interface---v021-dev4)
|
||||
- [`thermion_flutter_web` - `v0.1.0+6`](#thermion_flutter_web---v0106)
|
||||
- [`thermion_flutter` - `v0.2.1-dev.4`](#thermion_flutter---v021-dev4)
|
||||
- [`thermion_flutter_ffi` - `v0.2.1-dev.4`](#thermion_flutter_ffi---v021-dev4)
|
||||
|
||||
Packages with dependency updates only:
|
||||
|
||||
> Packages listed below depend on other packages in this workspace that have had changes. Their versions have been incremented to bump the minimum dependency versions of the packages they depend upon in this project.
|
||||
|
||||
- `thermion_flutter_platform_interface` - `v0.2.1-dev.4`
|
||||
- `thermion_flutter_web` - `v0.1.0+6`
|
||||
- `thermion_flutter` - `v0.2.1-dev.4`
|
||||
- `thermion_flutter_ffi` - `v0.2.1-dev.4`
|
||||
|
||||
---
|
||||
|
||||
#### `thermion_dart` - `v0.2.1-dev.0.0.5`
|
||||
|
||||
- Bump "thermion_dart" to `0.2.1-dev.0.0.5`.
|
||||
|
||||
|
||||
## 2024-10-02
|
||||
|
||||
### Changes
|
||||
|
||||
---
|
||||
|
||||
Packages with breaking changes:
|
||||
|
||||
- There are no breaking changes in this release.
|
||||
|
||||
Packages with other changes:
|
||||
|
||||
- [`thermion_dart` - `v0.2.1-dev.0.0.4`](#thermion_dart---v021-dev004)
|
||||
- [`thermion_flutter_web` - `v0.1.0+5`](#thermion_flutter_web---v0105)
|
||||
- [`thermion_flutter` - `v0.2.1-dev.3`](#thermion_flutter---v021-dev3)
|
||||
- [`thermion_flutter_platform_interface` - `v0.2.1-dev.3`](#thermion_flutter_platform_interface---v021-dev3)
|
||||
- [`thermion_flutter_ffi` - `v0.2.1-dev.3`](#thermion_flutter_ffi---v021-dev3)
|
||||
|
||||
Packages with dependency updates only:
|
||||
|
||||
> Packages listed below depend on other packages in this workspace that have had changes. Their versions have been incremented to bump the minimum dependency versions of the packages they depend upon in this project.
|
||||
|
||||
- `thermion_flutter_web` - `v0.1.0+5`
|
||||
- `thermion_flutter` - `v0.2.1-dev.3`
|
||||
- `thermion_flutter_platform_interface` - `v0.2.1-dev.3`
|
||||
- `thermion_flutter_ffi` - `v0.2.1-dev.3`
|
||||
|
||||
---
|
||||
|
||||
#### `thermion_dart` - `v0.2.1-dev.0.0.4`
|
||||
|
||||
|
||||
## 2024-10-02
|
||||
|
||||
### Changes
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
## 0.2.1-dev.0.0.5
|
||||
|
||||
- Bump "thermion_dart" to `0.2.1-dev.0.0.5`.
|
||||
|
||||
## 0.2.1-dev.0.0.4
|
||||
|
||||
## 0.2.1-dev.0.0.3
|
||||
|
||||
- Bump "thermion_dart" to `0.2.1-dev.0.0.3`.
|
||||
|
||||
@@ -3,4 +3,5 @@ library;
|
||||
export 'src/input_handler.dart';
|
||||
export 'src/delegates.dart';
|
||||
export 'src/delegate_gesture_handler.dart';
|
||||
export 'src/implementations/default_pick_delegate.dart';
|
||||
export 'src/implementations/third_person_camera_delegate.dart';
|
||||
|
||||
@@ -10,9 +10,11 @@ class DelegateInputHandler implements InputHandler {
|
||||
final ThermionViewer viewer;
|
||||
|
||||
Stream<List<InputType>> get gestures => _gesturesController.stream;
|
||||
|
||||
final _gesturesController = StreamController<List<InputType>>.broadcast();
|
||||
|
||||
Stream get cameraUpdated => _cameraUpdatedController.stream;
|
||||
final _cameraUpdatedController = StreamController.broadcast();
|
||||
|
||||
final _logger = Logger("DelegateInputHandler");
|
||||
|
||||
InputHandlerDelegate? transformDelegate;
|
||||
@@ -75,13 +77,20 @@ class DelegateInputHandler implements InputHandler {
|
||||
factory DelegateInputHandler.flight(ThermionViewer viewer,
|
||||
{PickDelegate? pickDelegate,
|
||||
bool freeLook = false,
|
||||
double panSensitivity = 0.1,
|
||||
double movementSensitivity = 0.1,
|
||||
double rotateSensitivity = 0.01,
|
||||
double? clampY,
|
||||
ThermionEntity? entity}) =>
|
||||
DelegateInputHandler(
|
||||
viewer: viewer,
|
||||
pickDelegate: pickDelegate,
|
||||
transformDelegate: FreeFlightInputHandlerDelegate(viewer,
|
||||
clampY: clampY, entity: entity),
|
||||
clampY: clampY,
|
||||
entity: entity,
|
||||
rotationSensitivity: rotateSensitivity,
|
||||
panSensitivity: panSensitivity,
|
||||
movementSensitivity: movementSensitivity),
|
||||
actions: {
|
||||
InputType.MMB_HOLD_AND_MOVE: InputAction.ROTATE,
|
||||
InputType.SCROLLWHEEL: InputAction.TRANSLATE,
|
||||
@@ -134,6 +143,7 @@ class DelegateInputHandler implements InputHandler {
|
||||
break;
|
||||
}
|
||||
|
||||
// ignore: unnecessary_null_comparison
|
||||
if (keyType != null) {
|
||||
keyAction = _actions[keyType];
|
||||
|
||||
@@ -150,10 +160,11 @@ class DelegateInputHandler implements InputHandler {
|
||||
|
||||
await transformDelegate?.execute();
|
||||
var updates = _inputDeltas.keys.followedBy(keyTypes).toList();
|
||||
if(updates.isNotEmpty) {
|
||||
if (updates.isNotEmpty) {
|
||||
_gesturesController.add(updates);
|
||||
_cameraUpdatedController.add(true);
|
||||
}
|
||||
|
||||
|
||||
_inputDeltas.clear();
|
||||
_processing = false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
class DefaultPickDelegate extends PickDelegate {
|
||||
final ThermionViewer viewer;
|
||||
|
||||
const DefaultPickDelegate(this.viewer);
|
||||
|
||||
@override
|
||||
void pick(Vector2 location) {
|
||||
viewer.pick(location.x.toInt(), location.y.toInt());
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import '../../../viewer/src/shared_types/camera.dart';
|
||||
import '../../../viewer/viewer.dart';
|
||||
import '../../input.dart';
|
||||
import '../input_handler.dart';
|
||||
import 'dart:math';
|
||||
|
||||
class FixedOrbitRotateInputHandlerDelegate implements InputHandlerDelegate {
|
||||
final ThermionViewer viewer;
|
||||
@@ -46,15 +45,16 @@ class FixedOrbitRotateInputHandlerDelegate implements InputHandlerDelegate {
|
||||
_queuedRotationDelta += Vector2(delta.x, delta.y);
|
||||
break;
|
||||
case InputAction.TRANSLATE:
|
||||
_queuedZoomDelta += delta!.z;
|
||||
_queuedZoomDelta += delta.z;
|
||||
break;
|
||||
case InputAction.PICK:
|
||||
// Assuming PICK is used for zoom in this context
|
||||
_queuedZoomDelta += delta.z;
|
||||
break;
|
||||
case InputAction.NONE:
|
||||
// Do nothing
|
||||
break;
|
||||
case InputAction.ZOOM:
|
||||
_queuedZoomDelta += delta.z;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ class FreeFlightInputHandlerDelegate implements InputHandlerDelegate {
|
||||
static final Vector3 _right = Vector3(1, 0, 0);
|
||||
|
||||
Vector2 _queuedRotationDelta = Vector2.zero();
|
||||
Vector2 _queuedPanDelta = Vector2.zero();
|
||||
Vector3 _queuedTranslateDelta = Vector3.zero();
|
||||
double _queuedZoomDelta = 0.0;
|
||||
Vector3 _queuedMoveDelta = Vector3.zero();
|
||||
|
||||
@@ -49,14 +49,16 @@ class FreeFlightInputHandlerDelegate implements InputHandlerDelegate {
|
||||
_queuedRotationDelta += Vector2(delta.x, delta.y);
|
||||
break;
|
||||
case InputAction.TRANSLATE:
|
||||
_queuedPanDelta += Vector2(delta.x, delta.y);
|
||||
_queuedZoomDelta += delta.z;
|
||||
_queuedTranslateDelta += delta;
|
||||
break;
|
||||
case InputAction.PICK:
|
||||
_queuedZoomDelta += delta.z;
|
||||
break;
|
||||
case InputAction.NONE:
|
||||
break;
|
||||
case InputAction.ZOOM:
|
||||
_queuedZoomDelta += delta.z;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +73,7 @@ class FreeFlightInputHandlerDelegate implements InputHandlerDelegate {
|
||||
_executing = true;
|
||||
|
||||
if (_queuedRotationDelta.length2 == 0.0 &&
|
||||
_queuedPanDelta.length2 == 0.0 &&
|
||||
_queuedTranslateDelta.length2 == 0.0 &&
|
||||
_queuedZoomDelta == 0.0 &&
|
||||
_queuedMoveDelta.length2 == 0.0) {
|
||||
_executing = false;
|
||||
@@ -79,9 +81,9 @@ class FreeFlightInputHandlerDelegate implements InputHandlerDelegate {
|
||||
}
|
||||
|
||||
final activeCamera = await viewer.getActiveCamera();
|
||||
Matrix4 currentViewMatrix = await activeCamera.getViewMatrix();
|
||||
|
||||
Matrix4 currentTransform = await viewer.getLocalTransform(await entity);
|
||||
Vector3 currentPosition = currentTransform.getTranslation();
|
||||
|
||||
Quaternion currentRotation =
|
||||
Quaternion.fromRotation(currentTransform.getRotation());
|
||||
|
||||
@@ -92,10 +94,8 @@ class FreeFlightInputHandlerDelegate implements InputHandlerDelegate {
|
||||
|
||||
// Apply rotation
|
||||
if (_queuedRotationDelta.length2 > 0.0) {
|
||||
double deltaX =
|
||||
_queuedRotationDelta.x * rotationSensitivity;
|
||||
double deltaY =
|
||||
_queuedRotationDelta.y * rotationSensitivity;
|
||||
double deltaX = _queuedRotationDelta.x * rotationSensitivity;
|
||||
double deltaY = _queuedRotationDelta.y * rotationSensitivity;
|
||||
|
||||
Quaternion yawRotation = Quaternion.axisAngle(_up, -deltaX);
|
||||
Quaternion pitchRotation = Quaternion.axisAngle(_right, -deltaY);
|
||||
@@ -105,15 +105,13 @@ class FreeFlightInputHandlerDelegate implements InputHandlerDelegate {
|
||||
}
|
||||
|
||||
// Apply pan
|
||||
if (_queuedPanDelta.length2 > 0.0) {
|
||||
Vector3 right = _right.clone()..applyQuaternion(currentRotation);
|
||||
Vector3 up = _up.clone()..applyQuaternion(currentRotation);
|
||||
if (_queuedTranslateDelta.length2 > 0.0) {
|
||||
double deltaX = _queuedTranslateDelta.x * panSensitivity;
|
||||
double deltaY = _queuedTranslateDelta.y * panSensitivity;
|
||||
double deltaZ = -_queuedTranslateDelta.z * panSensitivity;
|
||||
|
||||
double deltaX = _queuedPanDelta.x * panSensitivity;
|
||||
double deltaY = _queuedPanDelta.y * panSensitivity;
|
||||
|
||||
relativeTranslation += right * deltaX + up * deltaY;
|
||||
_queuedPanDelta = Vector2.zero();
|
||||
relativeTranslation += _right * deltaX + _up * deltaY + _forward * deltaZ;
|
||||
_queuedTranslateDelta = Vector3.zero();
|
||||
}
|
||||
|
||||
// Apply zoom
|
||||
@@ -129,9 +127,10 @@ class FreeFlightInputHandlerDelegate implements InputHandlerDelegate {
|
||||
Vector3 right = _right.clone()..applyQuaternion(currentRotation);
|
||||
Vector3 up = _up.clone()..applyQuaternion(currentRotation);
|
||||
|
||||
relativeTranslation += right * _queuedMoveDelta.x +
|
||||
up * _queuedMoveDelta.y +
|
||||
forward * _queuedMoveDelta.z;
|
||||
relativeTranslation += (right * _queuedMoveDelta.x +
|
||||
up * _queuedMoveDelta.y +
|
||||
forward * _queuedMoveDelta.z) *
|
||||
movementSensitivity;
|
||||
|
||||
_queuedMoveDelta = Vector3.zero();
|
||||
}
|
||||
|
||||
@@ -56,6 +56,8 @@ class OverTheShoulderCameraDelegate implements InputHandlerDelegate {
|
||||
break;
|
||||
case InputAction.NONE:
|
||||
break;
|
||||
case InputAction.ZOOM:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,10 +24,10 @@ enum InputType {
|
||||
|
||||
enum PhysicalKey { W, A, S, D }
|
||||
|
||||
enum InputAction { TRANSLATE, ROTATE, PICK, NONE }
|
||||
enum InputAction { TRANSLATE, ROTATE, PICK, ZOOM, NONE }
|
||||
|
||||
abstract class InputHandler {
|
||||
Stream<List<InputType>> get gestures;
|
||||
Stream get cameraUpdated;
|
||||
|
||||
Future<void> onPointerHover(Vector2 localPosition, Vector2 delta);
|
||||
Future<void> onPointerScroll(Vector2 localPosition, double scrollDelta);
|
||||
|
||||
44
thermion_dart/lib/src/utils/src/axis.dart
Normal file
44
thermion_dart/lib/src/utils/src/axis.dart
Normal file
@@ -0,0 +1,44 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
import '../../viewer/viewer.dart';
|
||||
|
||||
class Axis {
|
||||
final ThermionViewer _viewer;
|
||||
final ThermionEntity xAxis;
|
||||
final ThermionEntity yAxis;
|
||||
final ThermionEntity zAxis;
|
||||
|
||||
Axis._(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),
|
||||
materialInstance: await viewer!.createUnlitMaterialInstance());
|
||||
final yAxis = await viewer!.createGeometry(
|
||||
Geometry(Float32List.fromList([0, 0, 0, 0, 10, 0]), [0, 1],
|
||||
primitiveType: PrimitiveType.LINES),
|
||||
materialInstance: await viewer!.createUnlitMaterialInstance());
|
||||
final zAxis = await viewer!.createGeometry(
|
||||
Geometry(Float32List.fromList([0, 0, 0, 0, 0, 10]), [0, 1],
|
||||
primitiveType: PrimitiveType.LINES),
|
||||
materialInstance: await viewer!.createUnlitMaterialInstance());
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import 'dart:io';
|
||||
|
||||
import 'package:ffi/ffi.dart';
|
||||
|
||||
import '../viewer/src/ffi/src/thermion_dart.g.dart';
|
||||
import '../../viewer/src/ffi/src/thermion_dart.g.dart';
|
||||
|
||||
class DartResourceLoader {
|
||||
static final _assets = <int, Pointer>{};
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'dart:math';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import '../../thermion_dart.dart';
|
||||
import '../../../thermion_dart.dart';
|
||||
|
||||
class GeometryHelper {
|
||||
static Geometry sphere({bool normals = true, bool uvs = true}) {
|
||||
4
thermion_dart/lib/src/utils/utils.dart
Normal file
4
thermion_dart/lib/src/utils/utils.dart
Normal file
@@ -0,0 +1,4 @@
|
||||
library;
|
||||
|
||||
export 'src/geometry.dart';
|
||||
export 'src/axis.dart';
|
||||
@@ -2,7 +2,7 @@ import 'dart:ffi';
|
||||
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
import '../../../../utils/matrix.dart';
|
||||
import '../../../../utils/src/matrix.dart';
|
||||
import '../../thermion_viewer_base.dart';
|
||||
import 'thermion_dart.g.dart' as g;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import 'dart:ffi';
|
||||
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_dart.g.dart';
|
||||
|
||||
import '../../../../utils/gizmo.dart';
|
||||
import '../../../../utils/src/gizmo.dart';
|
||||
import '../../../viewer.dart';
|
||||
|
||||
class FFIGizmo extends BaseGizmo {
|
||||
|
||||
@@ -16,16 +16,6 @@ external ffi.Pointer<ffi.Void> make_resource_loader(
|
||||
ffi.Pointer<ffi.Void> owner,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Pointer<TViewer> Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>,
|
||||
ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Char>)>(isLeaf: true)
|
||||
external ffi.Pointer<TViewer> Viewer_create(
|
||||
ffi.Pointer<ffi.Void> context,
|
||||
ffi.Pointer<ffi.Void> loader,
|
||||
ffi.Pointer<ffi.Void> platform,
|
||||
ffi.Pointer<ffi.Char> uberArchivePath,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>)>(isLeaf: true)
|
||||
external void destroy_filament_viewer(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
@@ -152,6 +142,28 @@ external void Viewer_setViewRenderable(
|
||||
bool renderable,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TViewer>,
|
||||
ffi.Pointer<TView>,
|
||||
ffi.Int,
|
||||
ffi.Int,
|
||||
ffi.Pointer<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(EntityId entityId, ffi.Int x, ffi.Int y,
|
||||
ffi.Pointer<TView> tView)>>)>(isLeaf: true)
|
||||
external void Viewer_pick(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
ffi.Pointer<TView> tView,
|
||||
int x,
|
||||
int y,
|
||||
ffi.Pointer<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(EntityId entityId, ffi.Int x, ffi.Int y,
|
||||
ffi.Pointer<TView> tView)>>
|
||||
callback,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Pointer<TEngine> Function(ffi.Pointer<TViewer>)>(isLeaf: true)
|
||||
external ffi.Pointer<TEngine> Viewer_getEngine(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
@@ -398,25 +410,6 @@ external bool set_morph_target_weights(
|
||||
int numWeights,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Bool Function(
|
||||
ffi.Pointer<TSceneManager>,
|
||||
EntityId,
|
||||
ffi.Pointer<ffi.Float>,
|
||||
ffi.Pointer<ffi.Int>,
|
||||
ffi.Int,
|
||||
ffi.Int,
|
||||
ffi.Float)>(isLeaf: true)
|
||||
external bool set_morph_animation(
|
||||
ffi.Pointer<TSceneManager> sceneManager,
|
||||
int entity,
|
||||
ffi.Pointer<ffi.Float> morphData,
|
||||
ffi.Pointer<ffi.Int> morphIndices,
|
||||
int numMorphTargets,
|
||||
int numFrames,
|
||||
double frameLengthInMs,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Pointer<TMaterialInstance> Function(
|
||||
ffi.Pointer<TSceneManager>, TMaterialKey)>(isLeaf: true)
|
||||
@@ -659,7 +652,7 @@ external ffi.Pointer<TScene> SceneManager_getScene(
|
||||
|
||||
@ffi.Native<
|
||||
EntityId Function(ffi.Pointer<TSceneManager>, ffi.Pointer<ffi.Uint8>,
|
||||
ffi.Size, ffi.Bool, ffi.Int, ffi.Int)>(isLeaf: true)
|
||||
ffi.Size, ffi.Bool, ffi.Int, ffi.Int, ffi.Bool)>(isLeaf: true)
|
||||
external int SceneManager_loadGlbFromBuffer(
|
||||
ffi.Pointer<TSceneManager> sceneManager,
|
||||
ffi.Pointer<ffi.Uint8> arg1,
|
||||
@@ -667,6 +660,26 @@ external int SceneManager_loadGlbFromBuffer(
|
||||
bool keepData,
|
||||
int priority,
|
||||
int layer,
|
||||
bool loadResourcesAsync,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Bool Function(
|
||||
ffi.Pointer<TSceneManager>,
|
||||
EntityId,
|
||||
ffi.Pointer<ffi.Float>,
|
||||
ffi.Pointer<ffi.Uint32>,
|
||||
ffi.Int,
|
||||
ffi.Int,
|
||||
ffi.Float)>(isLeaf: true)
|
||||
external bool SceneManager_setMorphAnimation(
|
||||
ffi.Pointer<TSceneManager> sceneManager,
|
||||
int entity,
|
||||
ffi.Pointer<ffi.Float> morphData,
|
||||
ffi.Pointer<ffi.Uint32> morphIndices,
|
||||
int numMorphTargets,
|
||||
int numFrames,
|
||||
double frameLengthInMs,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Bool Function(ffi.Pointer<TSceneManager>, EntityId)>(
|
||||
@@ -841,27 +854,6 @@ external int reveal_mesh(
|
||||
ffi.Pointer<ffi.Char> meshName,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TViewer>,
|
||||
ffi.Pointer<TView>,
|
||||
ffi.Int,
|
||||
ffi.Int,
|
||||
ffi.Pointer<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(
|
||||
EntityId entityId, ffi.Int x, ffi.Int y)>>)>(isLeaf: true)
|
||||
external void filament_pick(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
ffi.Pointer<TView> tView,
|
||||
int x,
|
||||
int y,
|
||||
ffi.Pointer<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(EntityId entityId, ffi.Int x, ffi.Int y)>>
|
||||
callback,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Pointer<ffi.Char> Function(
|
||||
ffi.Pointer<TSceneManager>, EntityId)>(isLeaf: true)
|
||||
@@ -1430,7 +1422,7 @@ external void Viewer_requestFrameRenderThread(
|
||||
external void View_setToneMappingRenderThread(
|
||||
ffi.Pointer<TView> tView,
|
||||
ffi.Pointer<TEngine> tEngine,
|
||||
int arg2,
|
||||
int thermion,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Double)>(isLeaf: true)
|
||||
@@ -1524,6 +1516,7 @@ external void remove_skybox_render_thread(
|
||||
ffi.Bool,
|
||||
ffi.Int,
|
||||
ffi.Int,
|
||||
ffi.Bool,
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(EntityId)>>)>(
|
||||
isLeaf: true)
|
||||
external void SceneManager_loadGlbFromBufferRenderThread(
|
||||
@@ -1534,6 +1527,7 @@ external void SceneManager_loadGlbFromBufferRenderThread(
|
||||
bool keepData,
|
||||
int priority,
|
||||
int layer,
|
||||
bool loadResourcesAsync,
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(EntityId)>> callback,
|
||||
);
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ import 'package:animation_tools_dart/animation_tools_dart.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_gizmo.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
import 'package:vector_math/vector_math_64.dart' as v64;
|
||||
import '../../../../utils/gizmo.dart';
|
||||
import '../../../../utils/matrix.dart';
|
||||
import '../../../../utils/src/gizmo.dart';
|
||||
import '../../../../utils/src/matrix.dart';
|
||||
import '../../events.dart';
|
||||
import '../../shared_types/view.dart';
|
||||
import '../../thermion_viewer_base.dart';
|
||||
@@ -83,9 +83,9 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
this._driver = driver ?? nullptr;
|
||||
this._sharedContext = sharedContext ?? nullptr;
|
||||
|
||||
// _onPickResultCallable =
|
||||
// NativeCallable<Void Function(EntityId entityId, Int x, Int y)>.listener(
|
||||
// _onPickResult);
|
||||
_onPickResultCallable =
|
||||
NativeCallable<Void Function(EntityId entityId, Int x, Int y, Pointer<TView> view)>.listener(
|
||||
_onPickResult);
|
||||
|
||||
_initialize();
|
||||
}
|
||||
@@ -523,8 +523,8 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
throw Exception("Not yet implemented");
|
||||
}
|
||||
final pathPtr = path.toNativeUtf8(allocator: allocator).cast<Char>();
|
||||
var entity = await withIntCallback((callback)=> load_glb_render_thread(
|
||||
_sceneManager!, pathPtr, numInstances, keepData, callback));
|
||||
var entity = await withIntCallback((callback) => load_glb_render_thread(
|
||||
_sceneManager!, pathPtr, numInstances, keepData, callback));
|
||||
|
||||
allocator.free(pathPtr);
|
||||
if (entity == _FILAMENT_ASSET_ERROR) {
|
||||
@@ -546,7 +546,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
int numInstances = 1,
|
||||
bool keepData = false,
|
||||
int priority = 4,
|
||||
int layer = 0}) async {
|
||||
int layer = 0, bool loadResourcesAsync=false}) async {
|
||||
if (unlit) {
|
||||
throw Exception("Not yet implemented");
|
||||
}
|
||||
@@ -557,7 +557,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
|
||||
var entity = await withIntCallback((callback) =>
|
||||
SceneManager_loadGlbFromBufferRenderThread(_sceneManager!, data.address,
|
||||
data.length, numInstances, keepData, priority, layer, callback));
|
||||
data.length, numInstances, keepData, priority, layer, loadResourcesAsync, callback));
|
||||
|
||||
if (entity == _FILAMENT_ASSET_ERROR) {
|
||||
throw Exception("An error occurred loading GLB from buffer");
|
||||
@@ -729,7 +729,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
var meshEntity = meshEntities[i];
|
||||
|
||||
if (targetMeshNames?.contains(meshName) == false) {
|
||||
_logger.info("Skipping $meshName, not contained in target");
|
||||
// _logger.info("Skipping $meshName, not contained in target");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -749,39 +749,24 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
Child meshes: ${meshNames}""");
|
||||
}
|
||||
|
||||
var indices =
|
||||
intersection.map((m) => meshMorphTargets.indexOf(m)).toList();
|
||||
var indices = Uint32List.fromList(
|
||||
intersection.map((m) => meshMorphTargets.indexOf(m)).toList());
|
||||
|
||||
var frameData = animation.extract(morphTargets: intersection);
|
||||
// var frameData = animation.data;
|
||||
var frameData = animation.subset(intersection);
|
||||
|
||||
assert(frameData.length == animation.numFrames * intersection.length);
|
||||
assert(
|
||||
frameData.data.length == animation.numFrames * intersection.length);
|
||||
|
||||
var dataPtr = allocator<Float>(frameData.length);
|
||||
|
||||
// not currently working on WASM :( wasted a lot of time figuring that out as no error is thrown
|
||||
// dataPtr
|
||||
// .asTypedList(frameData.length)
|
||||
// .setRange(0, frameData.length, frameData);
|
||||
for (int i = 0; i < frameData.length; i++) {
|
||||
dataPtr[i] = frameData[i];
|
||||
}
|
||||
|
||||
final idxPtr = allocator<Int>(indices.length);
|
||||
|
||||
for (int i = 0; i < indices.length; i++) {
|
||||
idxPtr[i] = indices[i];
|
||||
}
|
||||
|
||||
var result = set_morph_animation(
|
||||
var result = SceneManager_setMorphAnimation(
|
||||
_sceneManager!,
|
||||
meshEntity,
|
||||
dataPtr,
|
||||
idxPtr,
|
||||
frameData.data.address,
|
||||
indices.address,
|
||||
indices.length,
|
||||
animation.numFrames,
|
||||
animation.frameLengthInMs);
|
||||
allocator.free(dataPtr);
|
||||
allocator.free(idxPtr);
|
||||
|
||||
if (!result) {
|
||||
throw Exception("Failed to set morph animation data for ${meshName}");
|
||||
}
|
||||
@@ -1484,14 +1469,11 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
final view = FFIView(viewPtr, _viewer!);
|
||||
final viewport = await view.getViewport();
|
||||
|
||||
// _pickResultController.add((
|
||||
// entity: entityId,
|
||||
// x: (x / pixelRatio).toDouble(),
|
||||
// y: (viewport.height - y) / pixelRatio
|
||||
// ));
|
||||
_pickResultController
|
||||
.add((entity: entityId, x: x.ceil(), y: (viewport.height - y).ceil()));
|
||||
}
|
||||
|
||||
late NativeCallable<Void Function(EntityId entityId, Int x, Int y)>
|
||||
late NativeCallable<Void Function(EntityId entityId, Int x, Int y, Pointer<TView> view)>
|
||||
_onPickResultCallable;
|
||||
|
||||
///
|
||||
@@ -1499,11 +1481,11 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
@override
|
||||
void pick(int x, int y) async {
|
||||
// x = (x * pixelRatio).ceil();
|
||||
// y = (viewportDimensions.$2 - (y * pixelRatio)).ceil();
|
||||
// final view = (await getViewAt(0)) as FFIView;
|
||||
// filament_pick(
|
||||
// _viewer!, view.view, x, y, _onPickResultCallable.nativeFunction);
|
||||
final view = (await getViewAt(0)) as FFIView;
|
||||
var viewport = await view.getViewport();
|
||||
y = (viewport.height - y).ceil();
|
||||
Viewer_pick(
|
||||
_viewer!, view.view, x, y, _onPickResultCallable.nativeFunction);
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:thermion_dart/src/viewer/src/events.dart';
|
||||
import '../../utils/gizmo.dart';
|
||||
import '../../utils/src/gizmo.dart';
|
||||
import 'shared_types/shared_types.dart';
|
||||
export 'shared_types/shared_types.dart';
|
||||
|
||||
@@ -56,8 +56,10 @@ abstract class ThermionViewer {
|
||||
///
|
||||
/// Render a single frame and copy the pixel buffer to [out].
|
||||
///
|
||||
Future<Uint8List> capture({covariant SwapChain? swapChain,
|
||||
covariant View? view, covariant RenderTarget? renderTarget});
|
||||
Future<Uint8List> capture(
|
||||
{covariant SwapChain? swapChain,
|
||||
covariant View? view,
|
||||
covariant RenderTarget? renderTarget});
|
||||
|
||||
///
|
||||
///
|
||||
@@ -214,12 +216,16 @@ abstract class ThermionViewer {
|
||||
/// Specify [numInstances] to create multiple instances (this is more efficient than dynamically instantating at a later time). You can then retrieve the created instances with [getInstances].
|
||||
/// If you want to be able to call [createInstance] at a later time, you must pass true for [keepData].
|
||||
/// If [keepData] is false, the source glTF data will be released and [createInstance] will throw an exception.
|
||||
/// If [loadResourcesAsync] is true, resources (textures, materials, etc) will
|
||||
/// be loaded asynchronously (so expect some material/texture pop-in);
|
||||
///
|
||||
///
|
||||
Future<ThermionEntity> loadGlbFromBuffer(Uint8List data,
|
||||
{int numInstances = 1,
|
||||
bool keepData = false,
|
||||
int priority = 4,
|
||||
int layer = 0});
|
||||
int layer = 0,
|
||||
bool loadResourcesAsync});
|
||||
|
||||
///
|
||||
/// Create a new instance of [entity].
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'dart:math';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:thermion_dart/src/utils/gizmo.dart';
|
||||
import 'package:thermion_dart/src/utils/src/gizmo.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/shared_types/swap_chain.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/shared_types/view.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
@@ -893,11 +893,7 @@ class ThermionViewerStub extends ThermionViewer {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ThermionEntity> loadGlbFromBuffer(Uint8List data, {int numInstances = 1, bool keepData = false, int priority = 4, int layer = 0}) {
|
||||
// TODO: implement loadGlbFromBuffer
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
Future setMaterialPropertyInt(ThermionEntity entity, String propertyName, int materialIndex, int value) {
|
||||
@@ -1060,6 +1056,12 @@ class ThermionViewerStub extends ThermionViewer {
|
||||
// TODO: implement getActiveCamera
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ThermionEntity> loadGlbFromBuffer(Uint8List data, {int numInstances = 1, bool keepData = false, int priority = 4, int layer = 0, bool loadResourcesAsync= false}) {
|
||||
// TODO: implement loadGlbFromBuffer
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
import '../../shared_types/camera.dart';
|
||||
import '../../thermion_viewer_base.dart';
|
||||
|
||||
class ThermionWasmCamera extends Camera {
|
||||
|
||||
@@ -2,4 +2,4 @@ library filament_dart;
|
||||
|
||||
export 'src/viewer/viewer.dart';
|
||||
export 'src/input/input.dart';
|
||||
export 'src/utils/geometry.dart';
|
||||
export 'src/utils/utils.dart';
|
||||
|
||||
@@ -98,7 +98,7 @@ namespace thermion
|
||||
void clearBackgroundImage();
|
||||
void setBackgroundImagePosition(float x, float y, bool clamp, uint32_t width, uint32_t height);
|
||||
|
||||
void pick(View *view, uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y));
|
||||
void pick(View *view, uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y, View *view));
|
||||
Engine* getEngine() {
|
||||
return _engine;
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace thermion
|
||||
/// @return an Entity representing the FilamentAsset associated with the loaded FilamentAsset.
|
||||
///
|
||||
EntityId loadGlb(const char *uri, int numInstances, bool keepData);
|
||||
EntityId loadGlbFromBuffer(const uint8_t *data, size_t length, int numInstances = 1, bool keepData = false, int priority = 4, int layer = 0);
|
||||
EntityId loadGlbFromBuffer(const uint8_t *data, size_t length, int numInstances = 1, bool keepData = false, int priority = 4, int layer = 0, bool loadResourcesAsync = false);
|
||||
EntityId createInstance(EntityId entityId);
|
||||
|
||||
void remove(EntityId entity);
|
||||
@@ -125,7 +125,7 @@ namespace thermion
|
||||
bool setMorphAnimationBuffer(
|
||||
EntityId entityId,
|
||||
const float *const morphData,
|
||||
const int *const morphIndices,
|
||||
const uint32_t *const morphIndices,
|
||||
int numMorphTargets,
|
||||
int numFrames,
|
||||
float frameLengthInMs);
|
||||
|
||||
@@ -85,6 +85,7 @@ extern "C"
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_setMainCamera(TViewer *tViewer, TView *tView);
|
||||
EMSCRIPTEN_KEEPALIVE TSwapChain* Viewer_getSwapChainAt(TViewer *tViewer, int index);
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_setViewRenderable(TViewer *viewer, TSwapChain *swapChain, TView* view, bool renderable);
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_pick(TViewer *viewer, TView* tView, int x, int y, void (*callback)(EntityId entityId, int x, int y, TView *tView));
|
||||
|
||||
// Engine
|
||||
EMSCRIPTEN_KEEPALIVE TEngine *Viewer_getEngine(TViewer* viewer);
|
||||
@@ -146,14 +147,6 @@ extern "C"
|
||||
EntityId entity,
|
||||
const float *const morphData,
|
||||
int numWeights);
|
||||
EMSCRIPTEN_KEEPALIVE bool set_morph_animation(
|
||||
TSceneManager *sceneManager,
|
||||
EntityId entity,
|
||||
const float *const morphData,
|
||||
const int *const morphIndices,
|
||||
int numMorphTargets,
|
||||
int numFrames,
|
||||
float frameLengthInMs);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TMaterialInstance *create_material_instance(TSceneManager *sceneManager, TMaterialKey materialConfig);
|
||||
EMSCRIPTEN_KEEPALIVE TMaterialInstance *create_unlit_material_instance(TSceneManager *sceneManager);
|
||||
@@ -209,7 +202,15 @@ extern "C"
|
||||
EMSCRIPTEN_KEEPALIVE TCamera* SceneManager_findCameraByName(TSceneManager* tSceneManager, EntityId entity, const char* name);
|
||||
EMSCRIPTEN_KEEPALIVE void SceneManager_setVisibilityLayer(TSceneManager *tSceneManager, EntityId entity, int layer);
|
||||
EMSCRIPTEN_KEEPALIVE TScene* SceneManager_getScene(TSceneManager *tSceneManager);
|
||||
EMSCRIPTEN_KEEPALIVE EntityId SceneManager_loadGlbFromBuffer(TSceneManager *sceneManager, const uint8_t *const, size_t length, bool keepData, int priority, int layer);
|
||||
EMSCRIPTEN_KEEPALIVE EntityId SceneManager_loadGlbFromBuffer(TSceneManager *sceneManager, const uint8_t *const, size_t length, bool keepData, int priority, int layer, bool loadResourcesAsync);
|
||||
EMSCRIPTEN_KEEPALIVE bool SceneManager_setMorphAnimation(
|
||||
TSceneManager *sceneManager,
|
||||
EntityId entity,
|
||||
const float *const morphData,
|
||||
const uint32_t *const morphIndices,
|
||||
int numMorphTargets,
|
||||
int numFrames,
|
||||
float frameLengthInMs);
|
||||
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE bool update_bone_matrices(TSceneManager *sceneManager, EntityId entityId);
|
||||
@@ -239,7 +240,7 @@ extern "C"
|
||||
EMSCRIPTEN_KEEPALIVE int hide_mesh(TSceneManager *sceneManager, EntityId entity, const char *meshName);
|
||||
EMSCRIPTEN_KEEPALIVE int reveal_mesh(TSceneManager *sceneManager, EntityId entity, const char *meshName);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void filament_pick(TViewer *viewer, TView* tView, int x, int y, void (*callback)(EntityId entityId, int x, int y));
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE const char *get_name_for_entity(TSceneManager *sceneManager, const EntityId entityId);
|
||||
EMSCRIPTEN_KEEPALIVE EntityId find_child_entity_by_name(TSceneManager *sceneManager, const EntityId parent, const char *name);
|
||||
EMSCRIPTEN_KEEPALIVE int get_entity_count(TSceneManager *sceneManager, const EntityId target, bool renderableOnly);
|
||||
|
||||
@@ -52,7 +52,7 @@ extern "C"
|
||||
void load_skybox_render_thread(TViewer *viewer, const char *skyboxPath, void (*onComplete)());
|
||||
void remove_skybox_render_thread(TViewer *viewer);
|
||||
|
||||
void SceneManager_loadGlbFromBufferRenderThread(TSceneManager *sceneManager, const uint8_t *const data, size_t length, int numInstances, bool keepData, int priority, int layer, void (*callback)(EntityId));
|
||||
void SceneManager_loadGlbFromBufferRenderThread(TSceneManager *sceneManager, const uint8_t *const data, size_t length, int numInstances, bool keepData, int priority, int layer, bool loadResourcesAsync, void (*callback)(EntityId));
|
||||
void load_glb_render_thread(TSceneManager *sceneManager, const char *assetPath, int numInstances, bool keepData, void (*callback)(EntityId));
|
||||
void load_gltf_render_thread(TSceneManager *sceneManager, const char *assetPath, const char *relativePath, bool keepData, void (*callback)(EntityId));
|
||||
void create_instance_render_thread(TSceneManager *sceneManager, EntityId entityId, void (*callback)(EntityId));
|
||||
|
||||
@@ -764,10 +764,10 @@ namespace thermion
|
||||
view->setStereoscopicOptions({.enabled = true});
|
||||
#endif
|
||||
|
||||
// there's a glitch on certain iGPUs where nothing will render when postprocessing is enabled and bloom is disabled
|
||||
// set bloom to a small value here
|
||||
view->setBloomOptions({.strength = 0.01});
|
||||
view->setDithering(filament::Dithering::NONE);
|
||||
// bloom can be a bit glitchy (some Intel iGPUs won't render when postprocessing is enabled and bloom is disabled,
|
||||
// and render targets on MacOS flicker when bloom is disabled.
|
||||
// Here, we enable bloom, but set to 0 strength
|
||||
view->setBloomOptions({.enabled=true, .strength = 0});
|
||||
view->setShadowingEnabled(false);
|
||||
view->setScreenSpaceRefractionEnabled(false);
|
||||
view->setPostProcessingEnabled(false);
|
||||
@@ -1198,9 +1198,8 @@ namespace thermion
|
||||
return _engine->getCameraComponent(Entity::import(entity));
|
||||
}
|
||||
|
||||
void FilamentViewer::pick(View *view, uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y))
|
||||
void FilamentViewer::pick(View *view, uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y, View *view))
|
||||
{
|
||||
|
||||
view->pick(x, y, [=](filament::View::PickingQueryResult const &result) {
|
||||
|
||||
if(_sceneManager->isGizmoEntity(result.renderable)) {
|
||||
@@ -1214,7 +1213,7 @@ namespace thermion
|
||||
};
|
||||
|
||||
if (nonPickableEntities.find(result.renderable) == nonPickableEntities.end()) {
|
||||
callback(Entity::smuggle(result.renderable), x, y);
|
||||
callback(Entity::smuggle(result.renderable), x, y, view);
|
||||
} });
|
||||
}
|
||||
|
||||
|
||||
@@ -257,7 +257,7 @@ namespace thermion
|
||||
|
||||
}
|
||||
|
||||
EntityId SceneManager::loadGlbFromBuffer(const uint8_t *data, size_t length, int numInstances, bool keepData, int priority, int layer)
|
||||
EntityId SceneManager::loadGlbFromBuffer(const uint8_t *data, size_t length, int numInstances, bool keepData, int priority, int layer, bool loadResourcesAsync)
|
||||
{
|
||||
|
||||
FilamentAsset *asset = nullptr;
|
||||
@@ -304,10 +304,18 @@ namespace thermion
|
||||
_gltfResourceLoader->asyncUpdateLoad();
|
||||
}
|
||||
#else
|
||||
if (!_gltfResourceLoader->loadResources(asset))
|
||||
{
|
||||
Log("Unknown error loading glb asset");
|
||||
return 0;
|
||||
if(loadResourcesAsync) {
|
||||
if (!_gltfResourceLoader->asyncBeginLoad(asset))
|
||||
{
|
||||
Log("Unknown error loading glb asset");
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (!_gltfResourceLoader->loadResources(asset))
|
||||
{
|
||||
Log("Unknown error loading glb asset");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -806,7 +814,7 @@ namespace thermion
|
||||
bool SceneManager::setMorphAnimationBuffer(
|
||||
EntityId entityId,
|
||||
const float *const morphData,
|
||||
const int *const morphIndices,
|
||||
const uint32_t *const morphIndices,
|
||||
int numMorphTargets,
|
||||
int numFrames,
|
||||
float frameLengthInMs)
|
||||
|
||||
@@ -50,6 +50,13 @@ extern "C"
|
||||
viewer->destroyRenderTarget(renderTarget);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_pick(TViewer *tViewer, TView* tView, int x, int y, void (*callback)(EntityId entityId, int x, int y, TView *tView))
|
||||
{
|
||||
auto *viewer = reinterpret_cast<FilamentViewer*>(tViewer);
|
||||
auto *view = reinterpret_cast<View*>(tView);
|
||||
((FilamentViewer *)viewer)->pick(view, static_cast<uint32_t>(x), static_cast<uint32_t>(y), reinterpret_cast<void (*)(EntityId entityId, int x, int y, View *view)>(callback));
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void destroy_filament_viewer(TViewer *viewer)
|
||||
{
|
||||
delete ((FilamentViewer *)viewer);
|
||||
@@ -162,7 +169,7 @@ extern "C"
|
||||
return ((SceneManager *)sceneManager)->loadGlb(assetPath, numInstances, keepData);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE EntityId SceneManager_loadGlbFromBuffer(TSceneManager *sceneManager, const uint8_t *const data, size_t length, bool keepData, int priority, int layer)
|
||||
EMSCRIPTEN_KEEPALIVE EntityId SceneManager_loadGlbFromBuffer(TSceneManager *sceneManager, const uint8_t *const data, size_t length, bool keepData, int priority, int layer, bool loadResourcesAsync)
|
||||
{
|
||||
return ((SceneManager *)sceneManager)->loadGlbFromBuffer((const uint8_t *)data, length, 1, keepData, priority, layer);
|
||||
}
|
||||
@@ -446,11 +453,11 @@ extern "C"
|
||||
return ((SceneManager *)sceneManager)->setMorphTargetWeights(asset, weights, numWeights);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE bool set_morph_animation(
|
||||
EMSCRIPTEN_KEEPALIVE bool SceneManager_setMorphAnimation(
|
||||
TSceneManager *sceneManager,
|
||||
EntityId asset,
|
||||
const float *const morphData,
|
||||
const int *const morphIndices,
|
||||
const uint32_t *const morphIndices,
|
||||
int numMorphTargets,
|
||||
int numFrames,
|
||||
float frameLengthInMs)
|
||||
@@ -793,13 +800,6 @@ extern "C"
|
||||
return ((SceneManager *)sceneManager)->reveal(asset, meshName);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void filament_pick(TViewer *tViewer, TView* tView, int x, int y, void (*callback)(EntityId entityId, int x, int y))
|
||||
{
|
||||
auto *viewer = reinterpret_cast<FilamentViewer*>(tViewer);
|
||||
auto *view = reinterpret_cast<View*>(tView);
|
||||
((FilamentViewer *)viewer)->pick(view, static_cast<uint32_t>(x), static_cast<uint32_t>(y), callback);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE const char *get_name_for_entity(TSceneManager *sceneManager, const EntityId entityId)
|
||||
{
|
||||
return ((SceneManager *)sceneManager)->getNameForEntity(entityId);
|
||||
|
||||
@@ -55,9 +55,10 @@ public:
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
this->_requestFrameRenderCallback = callback;
|
||||
_cv.notify_one();
|
||||
}
|
||||
|
||||
void iter()
|
||||
void iter()
|
||||
{
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
@@ -79,7 +80,7 @@ public:
|
||||
if (_accumulatedTime >= 1.0f) // Update FPS every second
|
||||
{
|
||||
_fps = _frameCount / _accumulatedTime;
|
||||
std::cout << "FPS: " << _fps << std::endl;
|
||||
// std::cout << "FPS: " << _fps << std::endl;
|
||||
_frameCount = 0;
|
||||
_accumulatedTime = 0.0f;
|
||||
}
|
||||
@@ -96,7 +97,7 @@ public:
|
||||
taskLock.lock();
|
||||
}
|
||||
|
||||
_cv.wait_for(taskLock, std::chrono::microseconds(1000), [this]
|
||||
_cv.wait_for(taskLock, std::chrono::microseconds(2000), [this]
|
||||
{ return !_tasks.empty() || _stop; });
|
||||
|
||||
}
|
||||
@@ -336,12 +337,13 @@ extern "C"
|
||||
bool keepData,
|
||||
int priority,
|
||||
int layer,
|
||||
bool loadResourcesAsync,
|
||||
void (*callback)(EntityId))
|
||||
{
|
||||
std::packaged_task<EntityId()> lambda(
|
||||
[=]() mutable
|
||||
{
|
||||
auto entity = SceneManager_loadGlbFromBuffer(sceneManager, data, length, keepData, priority, layer);
|
||||
auto entity = SceneManager_loadGlbFromBuffer(sceneManager, data, length, keepData, priority, layer, loadResourcesAsync);
|
||||
callback(entity);
|
||||
return entity;
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: thermion_dart
|
||||
description: 3D rendering toolkit for Dart.
|
||||
version: 0.2.1-dev.0.0.3
|
||||
version: 0.2.1-dev.0.0.5
|
||||
homepage: https://thermion.dev
|
||||
repository: https://github.com/nmfisher/thermion
|
||||
|
||||
@@ -11,7 +11,7 @@ dependencies:
|
||||
vector_math: ^2.1.2
|
||||
plugin_platform_interface: ^2.0.0
|
||||
ffi: ^2.1.2
|
||||
animation_tools_dart: ^0.0.4
|
||||
animation_tools_dart: ^0.1.0
|
||||
native_toolchain_c: ^0.4.2
|
||||
archive: ^3.6.1
|
||||
web: ^1.0.0
|
||||
|
||||
36
thermion_dart/test/animation_tests.dart
Normal file
36
thermion_dart/test/animation_tests.dart
Normal file
@@ -0,0 +1,36 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
import 'dart:typed_data';
|
||||
import 'package:animation_tools_dart/animation_tools_dart.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/events.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
import 'helpers.dart';
|
||||
|
||||
void main() async {
|
||||
final testHelper = TestHelper("animation");
|
||||
|
||||
group('morph animation tests', () {
|
||||
test('set morph animation', () async {
|
||||
var viewer = await testHelper.createViewer(
|
||||
bg: kRed, cameraPosition: Vector3(0, 0, 5));
|
||||
|
||||
final cube = await viewer
|
||||
.loadGlb("${testHelper.testDir}/assets/cube_with_morph_targets.glb");
|
||||
var morphData = MorphAnimationData(
|
||||
Float32List.fromList(List<double>.generate(60, (i) => i / 60)),
|
||||
["Key 1"]);
|
||||
|
||||
await viewer.setMorphAnimationData(cube, morphData);
|
||||
for (int i = 0; i < 60; i++) {
|
||||
await viewer.requestFrame();
|
||||
await Future.delayed(Duration(milliseconds: 17));
|
||||
}
|
||||
|
||||
await testHelper.capture(viewer, "morph_animation");
|
||||
await viewer.dispose();
|
||||
});
|
||||
});
|
||||
}
|
||||
Binary file not shown.
BIN
thermion_dart/test/assets/cube_with_morph_targets.glb
Normal file
BIN
thermion_dart/test/assets/cube_with_morph_targets.glb
Normal file
Binary file not shown.
@@ -6,7 +6,7 @@ import 'dart:typed_data';
|
||||
import 'package:ffi/ffi.dart';
|
||||
import 'package:image/image.dart';
|
||||
import 'swift/swift_bindings.g.dart';
|
||||
import 'package:thermion_dart/src/utils/dart_resources.dart';
|
||||
import 'package:thermion_dart/src/utils/src/dart_resources.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_dart.g.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_viewer_ffi.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/thermion_viewer_ffi.dart';
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:test/test.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
@@ -17,7 +19,8 @@ void main() async {
|
||||
var viewer = await testHelper.createViewer();
|
||||
|
||||
final texture = await testHelper.createTexture(500, 500);
|
||||
final renderTarget = await viewer.createRenderTarget(500, 500, texture.metalTextureAddress);
|
||||
final renderTarget = await viewer.createRenderTarget(
|
||||
500, 500, texture.metalTextureAddress);
|
||||
viewer.setRenderTarget(renderTarget);
|
||||
|
||||
await viewer.setBackgroundColor(1.0, 0, 0, 1);
|
||||
@@ -76,14 +79,15 @@ void main() async {
|
||||
|
||||
var mainCamera = await viewer.getMainCamera();
|
||||
mainCamera.setTransform(Matrix4.translation(Vector3(0, 0, 5)));
|
||||
final swapChain = await viewer.createSwapChain(1, 1);
|
||||
final swapChain = await viewer.createHeadlessSwapChain(1, 1);
|
||||
await testHelper.capture(
|
||||
viewer, "create_swapchain_default_view_default_swapchain");
|
||||
|
||||
final view = await viewer.createView();
|
||||
|
||||
final texture = await testHelper.createTexture(200, 400);
|
||||
final renderTarget = await viewer.createRenderTarget(200, 400, texture.metalTextureAddress);
|
||||
final renderTarget = await viewer.createRenderTarget(
|
||||
200, 400, texture.metalTextureAddress);
|
||||
await view.setRenderTarget(renderTarget);
|
||||
|
||||
await view.updateViewport(200, 400);
|
||||
@@ -100,5 +104,30 @@ void main() async {
|
||||
|
||||
await viewer.dispose();
|
||||
});
|
||||
|
||||
test('pick', () async {
|
||||
var viewer = await testHelper.createViewer(
|
||||
bg: kRed, cameraPosition: Vector3(0, 0, 5));
|
||||
|
||||
final cube = await viewer.createGeometry(GeometryHelper.cube());
|
||||
|
||||
final completer = Completer();
|
||||
late StreamSubscription listener;
|
||||
listener = viewer.pickResult.listen((result) async {
|
||||
completer.complete(result.entity);
|
||||
await listener.cancel();
|
||||
});
|
||||
|
||||
viewer.pick(250, 250);
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
await viewer.requestFrame();
|
||||
await Future.delayed(Duration(milliseconds: 100));
|
||||
}
|
||||
|
||||
expect(completer.isCompleted, true);
|
||||
expect(await completer.future, cube);
|
||||
await viewer.dispose();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import 'dart:math';
|
||||
import 'package:ffi/ffi.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'swift/swift_bindings.g.dart';
|
||||
import 'package:thermion_dart/src/utils/dart_resources.dart';
|
||||
import 'package:thermion_dart/src/utils/src/dart_resources.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_dart.g.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/thermion_viewer_ffi.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
|
||||
@@ -2,7 +2,7 @@ import 'dart:ffi';
|
||||
import 'dart:io';
|
||||
import 'package:ffi/ffi.dart';
|
||||
import 'swift/swift_bindings.g.dart';
|
||||
import 'package:thermion_dart/src/utils/dart_resources.dart';
|
||||
import 'package:thermion_dart/src/utils/src/dart_resources.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_dart.g.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/thermion_viewer_ffi.dart';
|
||||
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
## 0.2.1-dev.4
|
||||
|
||||
- Update a dependency to the latest release.
|
||||
|
||||
## 0.2.1-dev.3
|
||||
|
||||
- Update a dependency to the latest release.
|
||||
|
||||
## 0.2.1-dev.2
|
||||
|
||||
- Update a dependency to the latest release.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: thermion_flutter
|
||||
description: Flutter plugin for 3D rendering with the Thermion toolkit.
|
||||
version: 0.2.1-dev.2
|
||||
version: 0.2.1-dev.4
|
||||
homepage: https://thermion.dev
|
||||
repository: https://github.com/nmfisher/thermion
|
||||
|
||||
@@ -16,11 +16,11 @@ dependencies:
|
||||
vector_math: ^2.1.2
|
||||
plugin_platform_interface: ^2.0.0
|
||||
ffi: ^2.1.2
|
||||
animation_tools_dart: ^0.0.4
|
||||
thermion_dart: ^0.2.1-dev.0.0.3
|
||||
thermion_flutter_platform_interface: ^0.2.1-dev.2
|
||||
thermion_flutter_ffi: ^0.2.1-dev.2
|
||||
thermion_flutter_web: ^0.1.0+4
|
||||
animation_tools_dart: ^0.1.0
|
||||
thermion_dart: ^0.2.1-dev.0.0.5
|
||||
thermion_flutter_platform_interface: ^0.2.1-dev.4
|
||||
thermion_flutter_ffi: ^0.2.1-dev.4
|
||||
thermion_flutter_web: ^0.1.0+6
|
||||
logging: ^1.2.0
|
||||
web: ^1.0.0
|
||||
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
## 0.2.1-dev.4
|
||||
|
||||
- Update a dependency to the latest release.
|
||||
|
||||
## 0.2.1-dev.3
|
||||
|
||||
- Update a dependency to the latest release.
|
||||
|
||||
## 0.2.1-dev.2
|
||||
|
||||
- Update a dependency to the latest release.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: thermion_flutter_ffi
|
||||
description: An FFI interface for the thermion_flutter plugin (all platforms except web).
|
||||
repository: https://github.com/nmfisher/thermion_flutter/thermion_flutter
|
||||
version: 0.2.1-dev.2
|
||||
version: 0.2.1-dev.4
|
||||
|
||||
environment:
|
||||
sdk: ">=3.3.0 <4.0.0"
|
||||
@@ -22,8 +22,8 @@ dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
plugin_platform_interface: ^2.1.0
|
||||
thermion_flutter_platform_interface: ^0.2.1-dev.2
|
||||
thermion_dart: ^0.2.1-dev.0.0.3
|
||||
thermion_flutter_platform_interface: ^0.2.1-dev.4
|
||||
thermion_dart: ^0.2.1-dev.0.0.5
|
||||
logging: ^1.2.0
|
||||
|
||||
dev_dependencies:
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
## 0.2.1-dev.4
|
||||
|
||||
- Update a dependency to the latest release.
|
||||
|
||||
## 0.2.1-dev.3
|
||||
|
||||
- Update a dependency to the latest release.
|
||||
|
||||
## 0.2.1-dev.2
|
||||
|
||||
- Update a dependency to the latest release.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: thermion_flutter_platform_interface
|
||||
description: A common platform interface for the thermion_flutter plugin.
|
||||
repository: https://github.com/nmfisher/thermion_flutter/thermion_flutter
|
||||
version: 0.2.1-dev.2
|
||||
version: 0.2.1-dev.4
|
||||
|
||||
environment:
|
||||
sdk: ">=3.3.0 <4.0.0"
|
||||
@@ -11,7 +11,7 @@ dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
plugin_platform_interface: ^2.1.0
|
||||
thermion_dart: ^0.2.1-dev.0.0.3
|
||||
thermion_dart: ^0.2.1-dev.0.0.5
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
## 0.1.0+6
|
||||
|
||||
- Update a dependency to the latest release.
|
||||
|
||||
## 0.1.0+5
|
||||
|
||||
- Update a dependency to the latest release.
|
||||
|
||||
## 0.1.0+4
|
||||
|
||||
- Update a dependency to the latest release.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: thermion_flutter_web
|
||||
description: A web platform interface for the thermion_flutter plugin.
|
||||
repository: https://github.com/nmfisher/thermion_flutter/thermion_flutter
|
||||
version: 0.1.0+4
|
||||
version: 0.1.0+6
|
||||
|
||||
environment:
|
||||
sdk: ">=3.3.0 <4.0.0"
|
||||
@@ -20,8 +20,8 @@ dependencies:
|
||||
sdk: flutter
|
||||
plugin_platform_interface: ^2.1.0
|
||||
web: ^1.0.0
|
||||
thermion_dart: ^0.2.1-dev.0.0.3
|
||||
thermion_flutter_platform_interface: ^0.2.1-dev.2
|
||||
thermion_dart: ^0.2.1-dev.0.0.5
|
||||
thermion_flutter_platform_interface: ^0.2.1-dev.4
|
||||
flutter_web_plugins:
|
||||
sdk: flutter
|
||||
|
||||
|
||||
Reference in New Issue
Block a user