add pan camera implementation and fix velocity timer
This commit is contained in:
@@ -7,12 +7,28 @@ import 'package:vector_math/vector_math_64.dart';
|
|||||||
class DefaultPanCameraDelegate implements PanCameraDelegate {
|
class DefaultPanCameraDelegate implements PanCameraDelegate {
|
||||||
final ThermionViewer viewer;
|
final ThermionViewer viewer;
|
||||||
|
|
||||||
|
static const double _panSensitivity = 0.005;
|
||||||
|
|
||||||
DefaultPanCameraDelegate(this.viewer);
|
DefaultPanCameraDelegate(this.viewer);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> panCamera(Offset delta, Vector2? velocity) async {
|
Future<void> panCamera(Offset delta, Vector2? velocity) async {
|
||||||
// Implement panning logic here
|
double deltaX = delta.dx;
|
||||||
// This is a placeholder implementation
|
double deltaY = delta.dy;
|
||||||
print("Panning camera by $delta");
|
deltaX *= _panSensitivity * viewer.pixelRatio;
|
||||||
|
deltaY *= _panSensitivity * viewer.pixelRatio;
|
||||||
|
|
||||||
|
Matrix4 currentModelMatrix = await viewer.getCameraModelMatrix();
|
||||||
|
Vector3 currentPosition = currentModelMatrix.getTranslation();
|
||||||
|
Quaternion currentRotation = Quaternion.fromRotation(currentModelMatrix.getRotation());
|
||||||
|
|
||||||
|
Vector3 right = Vector3(1, 0, 0)..applyQuaternion(currentRotation);
|
||||||
|
Vector3 up = Vector3(0, 1, 0)..applyQuaternion(currentRotation);
|
||||||
|
|
||||||
|
Vector3 panOffset = right * -deltaX + up * deltaY;
|
||||||
|
Vector3 newPosition = currentPosition + panOffset;
|
||||||
|
|
||||||
|
Matrix4 newModelMatrix = Matrix4.compose(newPosition, currentRotation, Vector3(1, 1, 1));
|
||||||
|
await viewer.setCameraModelMatrix4(newModelMatrix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,11 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
|
import 'package:thermion_flutter/thermion/widgets/camera/gestures/v2/default_pan_camera_delegate.dart';
|
||||||
|
import 'package:thermion_flutter/thermion/widgets/camera/gestures/v2/default_velocity_delegate.dart';
|
||||||
|
import 'package:thermion_flutter/thermion/widgets/camera/gestures/v2/default_zoom_camera_delegate.dart';
|
||||||
import 'package:thermion_flutter/thermion/widgets/camera/gestures/v2/delegates.dart';
|
import 'package:thermion_flutter/thermion/widgets/camera/gestures/v2/delegates.dart';
|
||||||
|
import 'package:thermion_flutter/thermion/widgets/camera/gestures/v2/fixed_orbit_camera_rotation_delegate.dart';
|
||||||
import 'package:thermion_flutter/thermion_flutter.dart';
|
import 'package:thermion_flutter/thermion_flutter.dart';
|
||||||
|
|
||||||
class DelegateGestureHandler implements ThermionGestureHandler {
|
class DelegateGestureHandler implements ThermionGestureHandler {
|
||||||
@@ -16,6 +20,10 @@ class DelegateGestureHandler implements ThermionGestureHandler {
|
|||||||
ZoomCameraDelegate? zoomCameraDelegate;
|
ZoomCameraDelegate? zoomCameraDelegate;
|
||||||
VelocityDelegate? velocityDelegate;
|
VelocityDelegate? velocityDelegate;
|
||||||
|
|
||||||
|
// Timer for continuous movement
|
||||||
|
Timer? _velocityTimer;
|
||||||
|
static const _velocityUpdateInterval = Duration(milliseconds: 16); // ~60 FPS
|
||||||
|
|
||||||
DelegateGestureHandler({
|
DelegateGestureHandler({
|
||||||
required this.viewer,
|
required this.viewer,
|
||||||
required this.rotateCameraDelegate,
|
required this.rotateCameraDelegate,
|
||||||
@@ -24,11 +32,22 @@ class DelegateGestureHandler implements ThermionGestureHandler {
|
|||||||
required this.velocityDelegate,
|
required this.velocityDelegate,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
factory DelegateGestureHandler.withDefaults(ThermionViewer viewer) =>
|
||||||
|
DelegateGestureHandler(
|
||||||
|
viewer: viewer,
|
||||||
|
rotateCameraDelegate: FixedOrbitRotateCameraDelegate(viewer),
|
||||||
|
panCameraDelegate: DefaultPanCameraDelegate(viewer),
|
||||||
|
zoomCameraDelegate: DefaultZoomCameraDelegate(viewer),
|
||||||
|
velocityDelegate: DefaultVelocityDelegate());
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onPointerDown(Offset localPosition, int buttons) async {
|
Future<void> onPointerDown(Offset localPosition, int buttons) async {
|
||||||
velocityDelegate?.stopDeceleration();
|
velocityDelegate?.stopDeceleration();
|
||||||
|
_stopVelocityTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GestureType? _lastGestureType;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onPointerMove(
|
Future<void> onPointerMove(
|
||||||
Offset localPosition, Offset delta, int buttons) async {
|
Offset localPosition, Offset delta, int buttons) async {
|
||||||
@@ -37,7 +56,7 @@ class DelegateGestureHandler implements ThermionGestureHandler {
|
|||||||
GestureType gestureType;
|
GestureType gestureType;
|
||||||
if (buttons == kPrimaryMouseButton) {
|
if (buttons == kPrimaryMouseButton) {
|
||||||
gestureType = GestureType.POINTER1_MOVE;
|
gestureType = GestureType.POINTER1_MOVE;
|
||||||
} else if (buttons == kSecondaryMouseButton) {
|
} else if (buttons == kMiddleMouseButton) {
|
||||||
gestureType = GestureType.POINTER2_MOVE;
|
gestureType = GestureType.POINTER2_MOVE;
|
||||||
} else {
|
} else {
|
||||||
throw Exception("Unsupported button: $buttons");
|
throw Exception("Unsupported button: $buttons");
|
||||||
@@ -51,19 +70,58 @@ class DelegateGestureHandler implements ThermionGestureHandler {
|
|||||||
await panCameraDelegate?.panCamera(delta, velocityDelegate?.velocity);
|
await panCameraDelegate?.panCamera(delta, velocityDelegate?.velocity);
|
||||||
case GestureAction.ROTATE_CAMERA:
|
case GestureAction.ROTATE_CAMERA:
|
||||||
_currentState = ThermionGestureState.ROTATING;
|
_currentState = ThermionGestureState.ROTATING;
|
||||||
await rotateCameraDelegate?.rotateCamera(delta, velocityDelegate?.velocity);
|
await rotateCameraDelegate?.rotateCamera(
|
||||||
|
delta, velocityDelegate?.velocity);
|
||||||
case null:
|
case null:
|
||||||
// ignore;
|
// ignore;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw Exception("Unsupported gesture type : $gestureType ");
|
throw Exception("Unsupported gesture type : $gestureType ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_lastGestureType = gestureType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onPointerUp(int buttons) async {
|
Future<void> onPointerUp(int buttons) async {
|
||||||
_currentState = ThermionGestureState.NULL;
|
_currentState = ThermionGestureState.NULL;
|
||||||
velocityDelegate?.startDeceleration();
|
velocityDelegate?.startDeceleration();
|
||||||
|
_startVelocityTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _startVelocityTimer() {
|
||||||
|
_stopVelocityTimer(); // Ensure any existing timer is stopped
|
||||||
|
_velocityTimer = Timer.periodic(_velocityUpdateInterval, (timer) {
|
||||||
|
_applyVelocity();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _stopVelocityTimer() {
|
||||||
|
_velocityTimer?.cancel();
|
||||||
|
_velocityTimer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _applyVelocity() async {
|
||||||
|
final velocity = velocityDelegate?.velocity;
|
||||||
|
if (velocity == null || velocity.length < 0.1) {
|
||||||
|
_stopVelocityTimer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final lastAction = _actions[_lastGestureType];
|
||||||
|
switch (lastAction) {
|
||||||
|
case GestureAction.PAN_CAMERA:
|
||||||
|
await panCameraDelegate?.panCamera(
|
||||||
|
Offset(velocity.x, velocity.y), velocity);
|
||||||
|
case GestureAction.ROTATE_CAMERA:
|
||||||
|
await rotateCameraDelegate?.rotateCamera(
|
||||||
|
Offset(velocity.x, velocity.y), velocity);
|
||||||
|
default:
|
||||||
|
// Do nothing for other actions
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
velocityDelegate?.updateVelocity(Offset(velocity.x, velocity.y)); // Gradually reduce velocity
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -85,7 +143,8 @@ class DelegateGestureHandler implements ThermionGestureHandler {
|
|||||||
_currentState = ThermionGestureState.ZOOMING;
|
_currentState = ThermionGestureState.ZOOMING;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await zoomCameraDelegate?.zoomCamera(scrollDelta, velocityDelegate?.velocity);
|
await zoomCameraDelegate?.zoomCamera(
|
||||||
|
scrollDelta, velocityDelegate?.velocity);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
_logger.warning("Error during camera zoom: $e");
|
_logger.warning("Error during camera zoom: $e");
|
||||||
} finally {
|
} finally {
|
||||||
@@ -95,7 +154,8 @@ class DelegateGestureHandler implements ThermionGestureHandler {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
// Clean up any resources if needed
|
_stopVelocityTimer();
|
||||||
|
velocityDelegate?.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
Reference in New Issue
Block a user