chore: Dart Gizmo class cleanup

This commit is contained in:
Nick Fisher
2024-08-27 21:49:04 +08:00
parent 4a0f4e3ac8
commit 8b17916cd9
2 changed files with 56 additions and 46 deletions

View File

@@ -2,15 +2,17 @@ import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
import 'package:vector_math/vector_math_64.dart'; import 'package:vector_math/vector_math_64.dart';
abstract class AbstractGizmo { abstract class AbstractGizmo {
bool get isActive;
bool get isVisible;
bool get isHovered;
void translate(double transX, double transY); Future translate(double transX, double transY);
void reset(); void reset();
void attach(ThermionEntity entity); Future attach(ThermionEntity entity);
void detach(); Future detach();
Stream<Aabb2> get boundingBox; Stream<Aabb2> get boundingBox;

View File

@@ -4,7 +4,6 @@ import 'package:vector_math/vector_math_64.dart';
import '../thermion_viewer.dart'; import '../thermion_viewer.dart';
class Gizmo extends AbstractGizmo { class Gizmo extends AbstractGizmo {
final ThermionEntity x; final ThermionEntity x;
final ThermionEntity y; final ThermionEntity y;
final ThermionEntity z; final ThermionEntity z;
@@ -14,48 +13,56 @@ class Gizmo extends AbstractGizmo {
ThermionEntity? _activeAxis; ThermionEntity? _activeAxis;
ThermionEntity? _activeEntity; ThermionEntity? _activeEntity;
bool get isActive => _activeAxis != null;
bool _visible = false;
bool get isVisible => _visible;
bool _isHovered = false;
bool get isHovered => _isHovered;
final Set<ThermionEntity> ignore; final Set<ThermionEntity> ignore;
Stream<Aabb2> get boundingBox => _boundingBoxController.stream; Stream<Aabb2> get boundingBox => _boundingBoxController.stream;
final _boundingBoxController = StreamController<Aabb2>.broadcast(); final _boundingBoxController = StreamController<Aabb2>.broadcast();
Gizmo(this.x, this.y, this.z, this.center, this._viewer, Gizmo(this.x, this.y, this.z, this.center, this._viewer,
{this.ignore = const <ThermionEntity>{}}) { {this.ignore = const <ThermionEntity>{}}) {
_viewer.gizmoPickResult.listen(_onGizmoPickResult);
_viewer.pickResult.listen(_onPickResult); _viewer.pickResult.listen(_onPickResult);
}
Future _reveal() async {
await _viewer.reveal(x, null);
await _viewer.reveal(y, null);
await _viewer.reveal(z, null);
await _viewer.reveal(center, null);
} }
final _stopwatch = Stopwatch(); final _stopwatch = Stopwatch();
var _translation = Vector3.zero(); double _transX = 0.0;
double _transY = 0.0;
void translate(double transX, double transY) async { Future translate(double transX, double transY) async {
if (!_stopwatch.isRunning) { if (!_stopwatch.isRunning) {
_stopwatch.start(); _stopwatch.start();
} }
_translation = Vector3(_activeAxis == x ? 1.0 : 0.0, _transX += transX;
_transY += transY;
if (_stopwatch.elapsedMilliseconds < 16) {
return;
}
final axis = Vector3(_activeAxis == x ? 1.0 : 0.0,
_activeAxis == y ? 1.0 : 0.0, _activeAxis == z ? 1.0 : 0.0); _activeAxis == y ? 1.0 : 0.0, _activeAxis == z ? 1.0 : 0.0);
await _viewer.queueRelativePositionUpdateWorldAxis( await _viewer.queueRelativePositionUpdateWorldAxis(
_activeEntity!, _activeEntity!,
transX * _viewer.pixelRatio, _transX * _viewer.pixelRatio,
-transY * _viewer.pixelRatio, -_transY *
_translation.x, _viewer
_translation.y, .pixelRatio, // flip the sign because "up" in NDC Y axis is positive, but negative in Flutter
_translation.z); axis.x,
axis.y,
axis.z);
_transX = 0;
_transY = 0;
_stopwatch.reset(); _stopwatch.reset();
_translation = Vector3.zero();
} }
void reset() { void reset() {
@@ -63,42 +70,43 @@ class Gizmo extends AbstractGizmo {
} }
void _onPickResult(FilamentPickResult result) async { void _onPickResult(FilamentPickResult result) async {
// print( await attach(result.entity);
// "Pick result ${result}, x is ${x}, y is $y, z is $z, ignore is $ignore"); }
// if (ignore.contains(result)) {
// print("Ignore/detach"); void _onGizmoPickResult(FilamentPickResult result) async {
// detach();
// return;
// }
if (result.entity == x || result.entity == y || result.entity == z) { if (result.entity == x || result.entity == y || result.entity == z) {
_activeAxis = result.entity; _activeAxis = result.entity;
print("Set active axis to $_activeAxis"); _isHovered = true;
} else if (result.entity == 0) {
_activeAxis = null;
_isHovered = false;
} else { } else {
attach(result.entity); throw Exception("Unexpected gizmo pick result");
print("Attaching to ${result.entity}");
} }
} }
void attach(ThermionEntity entity) async { Future attach(ThermionEntity entity) async {
_activeAxis = null; _activeAxis = null;
if (entity == _activeEntity) {
return;
}
if (entity == center) {
_activeEntity = null;
return;
}
_visible = true;
_activeEntity = entity; _activeEntity = entity;
await _reveal(); await _viewer.setGizmoVisibility(true);
await _viewer.setParent(center, entity, preserveScaling: true);
await _viewer.setParent(center, entity);
_boundingBoxController.sink.add(await _viewer.getBoundingBox(x)); _boundingBoxController.sink.add(await _viewer.getBoundingBox(x));
} }
void detach() async { Future detach() async {
await _viewer.setParent(center, 0); await _viewer.setGizmoVisibility(false);
await _viewer.hide(x, null);
await _viewer.hide(y, null);
await _viewer.hide(z, null);
await _viewer.hide(center, null);
} }
@override @override
void checkHover(double x, double y) { void checkHover(double x, double y) {
_viewer.pick(x.toInt(), y.toInt()); _viewer.pickGizmo(x.toInt(), y.toInt());
} }
} }