diff --git a/thermion_dart/lib/thermion_dart/entities/abstract_gizmo.dart b/thermion_dart/lib/thermion_dart/entities/abstract_gizmo.dart index 30d5e5c1..790fcc57 100644 --- a/thermion_dart/lib/thermion_dart/entities/abstract_gizmo.dart +++ b/thermion_dart/lib/thermion_dart/entities/abstract_gizmo.dart @@ -1,6 +1,3 @@ - - - import 'package:thermion_dart/thermion_dart/thermion_viewer.dart'; import 'package:vector_math/vector_math_64.dart'; @@ -15,9 +12,7 @@ abstract class AbstractGizmo { void detach(); - Aabb2 boundingBox = Aabb2(); + Stream get boundingBox; - void checkHover(double x, double y) { - if(boundingBox.containsVector2(Vector2(x, y))); - } + void checkHover(double x, double y); } diff --git a/thermion_dart/lib/thermion_dart/entities/gizmo.dart b/thermion_dart/lib/thermion_dart/entities/gizmo.dart index 0434fe84..fac67297 100644 --- a/thermion_dart/lib/thermion_dart/entities/gizmo.dart +++ b/thermion_dart/lib/thermion_dart/entities/gizmo.dart @@ -1,15 +1,13 @@ -import 'dart:ffi'; - -import 'package:ffi/ffi.dart'; +import 'dart:async'; import 'package:thermion_dart/thermion_dart/entities/abstract_gizmo.dart'; import 'package:vector_math/vector_math_64.dart'; import '../thermion_viewer.dart'; class Gizmo extends AbstractGizmo { + final ThermionEntity x; final ThermionEntity y; final ThermionEntity z; - final ThermionEntity center; final ThermionViewer _viewer; @@ -20,11 +18,14 @@ class Gizmo extends AbstractGizmo { final Set ignore; - Aabb2 boundingBox = Aabb2(); + Stream get boundingBox => _boundingBoxController.stream; + final _boundingBoxController = StreamController.broadcast(); + Gizmo(this.x, this.y, this.z, this.center, this._viewer, {this.ignore = const {}}) { _viewer.pickResult.listen(_onPickResult); + } Future _reveal() async { @@ -42,19 +43,19 @@ class Gizmo extends AbstractGizmo { if (!_stopwatch.isRunning) { _stopwatch.start(); } - if (_activeAxis == x) { - _translation += Vector3(transX, 0.0, 0.0); - } else { - _translation += Vector3(0.0, transY, 0.0); - } - if (_stopwatch.elapsedMilliseconds > 16) { - await _viewer.queuePositionUpdate( - _activeEntity!, _translation.x, _translation.y, _translation.z, - relative: true); - _stopwatch.reset(); - _translation = Vector3.zero(); - } + _translation = Vector3(_activeAxis == x ? 1.0 : 0.0, + _activeAxis == y ? 1.0 : 0.0, _activeAxis == z ? 1.0 : 0.0); + + await _viewer.queueRelativePositionUpdateWorldAxis( + _activeEntity!, + transX * _viewer.pixelRatio, + -transY * _viewer.pixelRatio, + _translation.x, + _translation.y, + _translation.z); + _stopwatch.reset(); + _translation = Vector3.zero(); } void reset() { @@ -62,14 +63,19 @@ class Gizmo extends AbstractGizmo { } void _onPickResult(FilamentPickResult result) async { - if (ignore.contains(result)) { - detach(); - return; - } + // print( + // "Pick result ${result}, x is ${x}, y is $y, z is $z, ignore is $ignore"); + // if (ignore.contains(result)) { + // print("Ignore/detach"); + // detach(); + // return; + // } if (result.entity == x || result.entity == y || result.entity == z) { _activeAxis = result.entity; + print("Set active axis to $_activeAxis"); } else { attach(result.entity); + print("Attaching to ${result.entity}"); } } @@ -78,21 +84,21 @@ class Gizmo extends AbstractGizmo { _activeEntity = entity; await _reveal(); - await _viewer.setParent(x, entity); - await _viewer.setParent(y, entity); - await _viewer.setParent(z, entity); await _viewer.setParent(center, entity); - boundingBox = await _viewer.getBoundingBox(x); + + _boundingBoxController.sink.add(await _viewer.getBoundingBox(x)); } void detach() async { - await _viewer.setParent(x, 0); - await _viewer.setParent(y, 0); - await _viewer.setParent(z, 0); await _viewer.setParent(center, 0); await _viewer.hide(x, null); await _viewer.hide(y, null); await _viewer.hide(z, null); await _viewer.hide(center, null); } + + @override + void checkHover(double x, double y) { + _viewer.pick(x.toInt(), y.toInt()); + } } diff --git a/thermion_dart/lib/thermion_dart/thermion_viewer_ffi.dart b/thermion_dart/lib/thermion_dart/thermion_viewer_ffi.dart index 77a8776d..12a0b9a3 100644 --- a/thermion_dart/lib/thermion_dart/thermion_viewer_ffi.dart +++ b/thermion_dart/lib/thermion_dart/thermion_viewer_ffi.dart @@ -24,7 +24,7 @@ class ThermionViewerFFI extends ThermionViewer { SceneImpl? _scene; Scene get scene => _scene!; - double _pixelRatio = 1.0; + double pixelRatio = 1.0; Pointer? _sceneManager; @@ -85,6 +85,7 @@ class ThermionViewerFFI extends ThermionViewer { } Future updateViewportAndCameraProjection(double width, double height) async { + viewportDimensions = (width * pixelRatio, height * pixelRatio); await withVoidCallback((callback) { update_viewport_and_camera_projection_ffi( _viewer!, width.toInt(), height.toInt(), 1.0, callback); @@ -128,11 +129,11 @@ class ThermionViewerFFI extends ThermionViewer { await setCameraManipulatorOptions(zoomSpeed: 1.0); - final out = allocator(4); - get_gizmo(_sceneManager!, out); - _gizmo = Gizmo(out[0], out[1], out[2], out[3], this); - allocator.free(out); - + final gizmoEntities = allocator(4); + get_gizmo(_sceneManager!, gizmoEntities); + _gizmo = Gizmo(gizmoEntities[0], gizmoEntities[1], gizmoEntities[2], + gizmoEntities[3], this); + allocator.free(gizmoEntities); this._initialized.complete(true); } @@ -466,7 +467,7 @@ class ThermionViewerFFI extends ThermionViewer { /// @override Future panStart(double x, double y) async { - grab_begin(_viewer!, x * _pixelRatio, y * _pixelRatio, true); + grab_begin(_viewer!, x * pixelRatio, y * pixelRatio, true); } /// @@ -474,7 +475,7 @@ class ThermionViewerFFI extends ThermionViewer { /// @override Future panUpdate(double x, double y) async { - grab_update(_viewer!, x * _pixelRatio, y * _pixelRatio); + grab_update(_viewer!, x * pixelRatio, y * pixelRatio); } /// @@ -490,7 +491,7 @@ class ThermionViewerFFI extends ThermionViewer { /// @override Future rotateStart(double x, double y) async { - grab_begin(_viewer!, x * _pixelRatio, y * _pixelRatio, false); + grab_begin(_viewer!, x * pixelRatio, y * pixelRatio, false); } /// @@ -498,7 +499,7 @@ class ThermionViewerFFI extends ThermionViewer { /// @override Future rotateUpdate(double x, double y) async { - grab_update(_viewer!, x * _pixelRatio, y * _pixelRatio); + grab_update(_viewer!, x * pixelRatio, y * pixelRatio); } /// @@ -1136,12 +1137,19 @@ class ThermionViewerFFI extends ThermionViewer { set_camera_focal_length(_viewer!, focalLength); } + /// + /// + /// + Future getCameraFov(bool horizontal) async { + return get_camera_fov(_viewer!, horizontal); + } + /// /// /// @override - Future setCameraFov(double degrees, double width, double height) async { - set_camera_fov(_viewer!, degrees, width / height); + Future setCameraFov(double degrees, {bool horizontal = true}) async { + set_camera_fov(_viewer!, degrees, horizontal); } /// @@ -1319,6 +1327,12 @@ class ThermionViewerFFI extends ThermionViewer { queue_position_update(_sceneManager!, entity, x, y, z, relative); } + Future queueRelativePositionUpdateWorldAxis(ThermionEntity entity, + double viewportX, double viewportY, double x, double y, double z) async { + queue_relative_position_update_world_axis( + _sceneManager!, entity, viewportX, viewportY, x, y, z); + } + /// /// /// @@ -1359,8 +1373,8 @@ class ThermionViewerFFI extends ThermionViewer { void _onPickResult(ThermionEntity entityId, int x, int y) { _pickResultController.add(( entity: entityId, - x: (x / _pixelRatio).toDouble(), - y: (viewportDimensions.$2 - y) / _pixelRatio + x: (x / pixelRatio).toDouble(), + y: (viewportDimensions.$2 - y) / pixelRatio )); _scene!.registerSelected(entityId); } @@ -1375,11 +1389,10 @@ class ThermionViewerFFI extends ThermionViewer { void pick(int x, int y) async { _scene!.unregisterSelected(); - filament_pick( - _viewer!, - (x * _pixelRatio).toInt(), - (viewportDimensions.$2 - (y * _pixelRatio)).toInt(), - _onPickResultCallable.nativeFunction); + x = (x * pixelRatio).ceil(); + y = (viewportDimensions.$2 - (y * pixelRatio)).ceil(); + + filament_pick(_viewer!, x, y, _onPickResultCallable.nativeFunction); } /// @@ -1700,7 +1713,8 @@ class ThermionViewerFFI extends ThermionViewer { /// /// @override - Future setParent(ThermionEntity child, ThermionEntity parent, { bool preserveScaling = false}) async { + Future setParent(ThermionEntity child, ThermionEntity parent, + {bool preserveScaling = false}) async { if (_sceneManager == null) { throw Exception("Asset manager must be non-null"); } @@ -1738,10 +1752,20 @@ class ThermionViewerFFI extends ThermionViewer { set_priority(_sceneManager!, entityId, priority); } + /// + /// + /// @override Future getBoundingBox(ThermionEntity entityId) async { final result = get_bounding_box(_sceneManager!, entityId); return v64.Aabb2.minMax(v64.Vector2(result.minX, result.minY), v64.Vector2(result.maxX, result.maxY)); } + + /// + /// + /// + Future setLayerEnabled(int layer, bool enabled) async { + set_layer_enabled(_sceneManager!, layer, enabled); + } }