gesture detector fixes
This commit is contained in:
@@ -14,16 +14,19 @@ class DefaultZoomCameraDelegate {
|
|||||||
DefaultZoomCameraDelegate(this.viewer,
|
DefaultZoomCameraDelegate(this.viewer,
|
||||||
{this.zoomSensitivity = 0.005, this.getDistanceToTarget});
|
{this.zoomSensitivity = 0.005, this.getDistanceToTarget});
|
||||||
|
|
||||||
double calculateZoomDistance(double scrollDelta, Vector2? velocity, Vector3 cameraPosition) {
|
///
|
||||||
double? distanceToTarget = getDistanceToTarget?.call(cameraPosition);
|
/// Converts the given [scrollDelta] (usually somewhere between 1 and -1) to
|
||||||
double zoomDistance = scrollDelta * zoomSensitivity;
|
/// a percentage of the current camera distance (either to the origin,
|
||||||
if (distanceToTarget != null) {
|
/// or to a custom target) along its forward vector.
|
||||||
zoomDistance *= distanceToTarget;
|
/// In other words, "shift "
|
||||||
if (zoomDistance.abs() < 0.0001) {
|
///
|
||||||
zoomDistance = scrollDelta * zoomSensitivity;
|
double calculateZoomFactor(
|
||||||
}
|
double scrollDelta, Vector2? velocity) {
|
||||||
|
double zoomFactor = scrollDelta * zoomSensitivity;
|
||||||
|
if (zoomFactor.abs() < 0.0001) {
|
||||||
|
zoomFactor = scrollDelta * zoomSensitivity;
|
||||||
}
|
}
|
||||||
return max(zoomDistance, scrollDelta * zoomSensitivity);
|
return zoomFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -36,7 +39,7 @@ class DefaultZoomCameraDelegate {
|
|||||||
forwardVector.normalize();
|
forwardVector.normalize();
|
||||||
|
|
||||||
var zoomDistance =
|
var zoomDistance =
|
||||||
calculateZoomDistance(scrollDelta, velocity, cameraPosition);
|
calculateZoomFactor(scrollDelta, velocity);
|
||||||
|
|
||||||
Vector3 newPosition = cameraPosition + (forwardVector * zoomDistance);
|
Vector3 newPosition = cameraPosition + (forwardVector * zoomDistance);
|
||||||
await viewer.setCameraPosition(newPosition.x, newPosition.y, newPosition.z);
|
await viewer.setCameraPosition(newPosition.x, newPosition.y, newPosition.z);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import 'package:thermion_flutter/thermion/widgets/camera/gestures/v2/delegates.d
|
|||||||
import 'package:thermion_flutter/thermion/widgets/camera/gestures/v2/fixed_orbit_camera_rotation_delegate.dart';
|
import 'package:thermion_flutter/thermion/widgets/camera/gestures/v2/fixed_orbit_camera_rotation_delegate.dart';
|
||||||
import 'package:thermion_flutter/thermion/widgets/camera/gestures/v2/free_flight_camera_delegate.dart';
|
import 'package:thermion_flutter/thermion/widgets/camera/gestures/v2/free_flight_camera_delegate.dart';
|
||||||
import 'package:thermion_flutter/thermion_flutter.dart';
|
import 'package:thermion_flutter/thermion_flutter.dart';
|
||||||
|
import 'package:vector_math/vector_math_64.dart';
|
||||||
|
|
||||||
class DelegateGestureHandler implements ThermionGestureHandler {
|
class DelegateGestureHandler implements ThermionGestureHandler {
|
||||||
final ThermionViewer viewer;
|
final ThermionViewer viewer;
|
||||||
@@ -48,10 +49,16 @@ class DelegateGestureHandler implements ThermionGestureHandler {
|
|||||||
_initializeAccumulatedDeltas();
|
_initializeAccumulatedDeltas();
|
||||||
}
|
}
|
||||||
|
|
||||||
factory DelegateGestureHandler.fixedOrbit(ThermionViewer viewer) =>
|
factory DelegateGestureHandler.fixedOrbit(ThermionViewer viewer,
|
||||||
|
{double? Function(Vector3)? getDistanceToTarget,
|
||||||
|
double rotationSensitivity = 0.001,
|
||||||
|
double zoomSensitivity = 0.001}) =>
|
||||||
DelegateGestureHandler(
|
DelegateGestureHandler(
|
||||||
viewer: viewer,
|
viewer: viewer,
|
||||||
cameraDelegate: FixedOrbitRotateCameraDelegate(viewer),
|
cameraDelegate: FixedOrbitRotateCameraDelegate(viewer,
|
||||||
|
getDistanceToTarget: getDistanceToTarget,
|
||||||
|
rotationSensitivity: rotationSensitivity,
|
||||||
|
zoomSensitivity: zoomSensitivity),
|
||||||
velocityDelegate: DefaultVelocityDelegate(),
|
velocityDelegate: DefaultVelocityDelegate(),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -96,7 +103,8 @@ class DelegateGestureHandler implements ThermionGestureHandler {
|
|||||||
// Do nothing
|
// Do nothing
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
_logger.warning("Unsupported gesture action: $action for type: $gestureType");
|
_logger.warning(
|
||||||
|
"Unsupported gesture action: $action for type: $gestureType");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,12 +113,13 @@ class DelegateGestureHandler implements ThermionGestureHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_accumulatedScrollDelta != 0.0) {
|
if (_accumulatedScrollDelta != 0.0) {
|
||||||
await cameraDelegate?.zoom(_accumulatedScrollDelta, velocityDelegate?.velocity);
|
await cameraDelegate?.zoom(
|
||||||
|
_accumulatedScrollDelta, velocityDelegate?.velocity);
|
||||||
_accumulatedScrollDelta = 0.0;
|
_accumulatedScrollDelta = 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onPointerDown(Offset localPosition, int buttons) async {
|
Future<void> onPointerDown(Offset localPosition, int buttons) async {
|
||||||
velocityDelegate?.stopDeceleration();
|
velocityDelegate?.stopDeceleration();
|
||||||
_activePointers++;
|
_activePointers++;
|
||||||
@@ -120,13 +129,18 @@ class DelegateGestureHandler implements ThermionGestureHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onPointerMove(Offset localPosition, Offset delta, int buttons) async {
|
Future<void> onPointerMove(
|
||||||
|
Offset localPosition, Offset delta, int buttons) async {
|
||||||
GestureType gestureType = _getGestureTypeFromButtons(buttons);
|
GestureType gestureType = _getGestureTypeFromButtons(buttons);
|
||||||
if (gestureType == GestureType.MMB_HOLD_AND_MOVE ||
|
if (gestureType == GestureType.MMB_HOLD_AND_MOVE ||
|
||||||
(_actions[GestureType.POINTER_MOVE] == GestureAction.ROTATE_CAMERA && gestureType == GestureType.POINTER_MOVE)) {
|
(_actions[GestureType.POINTER_MOVE] == GestureAction.ROTATE_CAMERA &&
|
||||||
_accumulatedDeltas[GestureType.MMB_HOLD_AND_MOVE] = (_accumulatedDeltas[GestureType.MMB_HOLD_AND_MOVE] ?? Offset.zero) + delta;
|
gestureType == GestureType.POINTER_MOVE)) {
|
||||||
|
_accumulatedDeltas[GestureType.MMB_HOLD_AND_MOVE] =
|
||||||
|
(_accumulatedDeltas[GestureType.MMB_HOLD_AND_MOVE] ?? Offset.zero) +
|
||||||
|
delta;
|
||||||
} else {
|
} else {
|
||||||
_accumulatedDeltas[gestureType] = (_accumulatedDeltas[gestureType] ?? Offset.zero) + delta;
|
_accumulatedDeltas[gestureType] =
|
||||||
|
(_accumulatedDeltas[gestureType] ?? Offset.zero) + delta;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,22 +156,26 @@ class DelegateGestureHandler implements ThermionGestureHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GestureType _getGestureTypeFromButtons(int buttons) {
|
GestureType _getGestureTypeFromButtons(int buttons) {
|
||||||
if (buttons & kPrimaryMouseButton != 0) return GestureType.LMB_HOLD_AND_MOVE;
|
if (buttons & kPrimaryMouseButton != 0)
|
||||||
if (buttons & kMiddleMouseButton != 0 || _isMiddleMouseButtonPressed) return GestureType.MMB_HOLD_AND_MOVE;
|
return GestureType.LMB_HOLD_AND_MOVE;
|
||||||
|
if (buttons & kMiddleMouseButton != 0 || _isMiddleMouseButtonPressed)
|
||||||
|
return GestureType.MMB_HOLD_AND_MOVE;
|
||||||
return GestureType.POINTER_MOVE;
|
return GestureType.POINTER_MOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onPointerHover(Offset localPosition, Offset delta) async {
|
Future<void> onPointerHover(Offset localPosition, Offset delta) async {
|
||||||
if (_actions[GestureType.POINTER_MOVE] == GestureAction.ROTATE_CAMERA) {
|
if (_actions[GestureType.POINTER_MOVE] == GestureAction.ROTATE_CAMERA) {
|
||||||
_accumulatedDeltas[GestureType.POINTER_MOVE] = (_accumulatedDeltas[GestureType.POINTER_MOVE] ?? Offset.zero) + delta;
|
_accumulatedDeltas[GestureType.POINTER_MOVE] =
|
||||||
|
(_accumulatedDeltas[GestureType.POINTER_MOVE] ?? Offset.zero) + delta;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onPointerScroll(Offset localPosition, double scrollDelta) async {
|
Future<void> onPointerScroll(Offset localPosition, double scrollDelta) async {
|
||||||
if (_actions[GestureType.SCROLLWHEEL] != GestureAction.ZOOM_CAMERA) {
|
if (_actions[GestureType.SCROLLWHEEL] != GestureAction.ZOOM_CAMERA) {
|
||||||
throw Exception("Unsupported action: ${_actions[GestureType.SCROLLWHEEL]}");
|
throw Exception(
|
||||||
|
"Unsupported action: ${_actions[GestureType.SCROLLWHEEL]}");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -203,6 +221,9 @@ class DelegateGestureHandler implements ThermionGestureHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool _handleKeyEvent(KeyEvent event) {
|
bool _handleKeyEvent(KeyEvent event) {
|
||||||
|
if (_actions[GestureType.KEYDOWN] == GestureAction.NONE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (event is KeyDownEvent || event is KeyRepeatEvent) {
|
if (event is KeyDownEvent || event is KeyRepeatEvent) {
|
||||||
cameraDelegate?.onKeypress(event.physicalKey);
|
cameraDelegate?.onKeypress(event.physicalKey);
|
||||||
return true;
|
return true;
|
||||||
@@ -212,4 +233,4 @@ class DelegateGestureHandler implements ThermionGestureHandler {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import 'package:vector_math/vector_math_64.dart';
|
|||||||
abstract class CameraDelegate {
|
abstract class CameraDelegate {
|
||||||
Future<void> rotate(Offset delta, Vector2? velocity);
|
Future<void> rotate(Offset delta, Vector2? velocity);
|
||||||
Future<void> pan(Offset delta, Vector2? velocity);
|
Future<void> pan(Offset delta, Vector2? velocity);
|
||||||
Future<void> zoom(double scrollDelta, Vector2? velocity);
|
Future<void> zoom(double yScrollDeltaInPixels, Vector2? velocity);
|
||||||
Future<void> onKeypress(PhysicalKeyboardKey key);
|
Future<void> onKeypress(PhysicalKeyboardKey key);
|
||||||
Future<void> onKeyRelease(PhysicalKeyboardKey key);
|
Future<void> onKeyRelease(PhysicalKeyboardKey key);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:math';
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:flutter/src/services/keyboard_key.g.dart';
|
import 'package:flutter/src/services/keyboard_key.g.dart';
|
||||||
@@ -10,21 +11,30 @@ import 'package:vector_math/vector_math_64.dart';
|
|||||||
|
|
||||||
class FixedOrbitRotateCameraDelegate implements CameraDelegate {
|
class FixedOrbitRotateCameraDelegate implements CameraDelegate {
|
||||||
final ThermionViewer viewer;
|
final ThermionViewer viewer;
|
||||||
static final _up = Vector3(0, 1, 0);
|
|
||||||
static final _forward = Vector3(0, 0, -1);
|
|
||||||
static final Vector3 _right = Vector3(1, 0, 0);
|
|
||||||
|
|
||||||
static const double _rotationSensitivity = 0.01;
|
double rotationSensitivity = 0.01;
|
||||||
|
|
||||||
late DefaultZoomCameraDelegate _zoomCameraDelegate;
|
late DefaultZoomCameraDelegate _zoomCameraDelegate;
|
||||||
|
|
||||||
Offset _accumulatedRotationDelta = Offset.zero;
|
Offset _accumulatedRotationDelta = Offset.zero;
|
||||||
double _accumulatedZoomDelta = 0.0;
|
double _accumulatedZoomDelta = 0.0;
|
||||||
|
|
||||||
|
static final _up = Vector3(0, 1, 0);
|
||||||
|
|
||||||
Timer? _updateTimer;
|
Timer? _updateTimer;
|
||||||
|
|
||||||
FixedOrbitRotateCameraDelegate(this.viewer) {
|
Vector3 _targetPosition = Vector3(0, 0, 0);
|
||||||
_zoomCameraDelegate = DefaultZoomCameraDelegate(this.viewer);
|
|
||||||
|
double? Function(Vector3)? getDistanceToTarget;
|
||||||
|
|
||||||
|
FixedOrbitRotateCameraDelegate(this.viewer,
|
||||||
|
{this.getDistanceToTarget,
|
||||||
|
double? rotationSensitivity,
|
||||||
|
double zoomSensitivity = 0.005}) {
|
||||||
|
_zoomCameraDelegate = DefaultZoomCameraDelegate(this.viewer,
|
||||||
|
zoomSensitivity: zoomSensitivity,
|
||||||
|
getDistanceToTarget: getDistanceToTarget);
|
||||||
|
this.rotationSensitivity = rotationSensitivity ?? 0.01;
|
||||||
_startUpdateTimer();
|
_startUpdateTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,64 +59,88 @@ class FixedOrbitRotateCameraDelegate implements CameraDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> zoom(double scrollDelta, Vector2? velocity) async {
|
Future<void> zoom(double yScrollDeltaInPixels, Vector2? velocity) async {
|
||||||
_accumulatedZoomDelta += scrollDelta;
|
if (yScrollDeltaInPixels > 1) {
|
||||||
|
_accumulatedZoomDelta++;
|
||||||
|
} else {
|
||||||
|
_accumulatedZoomDelta--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _applyAccumulatedUpdates() async {
|
Future<void> _applyAccumulatedUpdates() async {
|
||||||
if (_accumulatedRotationDelta != Offset.zero || _accumulatedZoomDelta != 0.0) {
|
if (_accumulatedRotationDelta.distanceSquared == 0.0 &&
|
||||||
Matrix4 currentModelMatrix = await viewer.getCameraModelMatrix();
|
_accumulatedZoomDelta == 0.0) {
|
||||||
Vector3 currentPosition = currentModelMatrix.getTranslation();
|
return;
|
||||||
double distance = currentPosition.length;
|
|
||||||
Quaternion currentRotation =
|
|
||||||
Quaternion.fromRotation(currentModelMatrix.getRotation());
|
|
||||||
|
|
||||||
// Apply rotation
|
|
||||||
if (_accumulatedRotationDelta != Offset.zero) {
|
|
||||||
double deltaX = _accumulatedRotationDelta.dx * _rotationSensitivity * viewer.pixelRatio;
|
|
||||||
double deltaY = _accumulatedRotationDelta.dy * _rotationSensitivity * viewer.pixelRatio;
|
|
||||||
|
|
||||||
Quaternion yawRotation = Quaternion.axisAngle(_up, -deltaX);
|
|
||||||
Quaternion pitchRotation = Quaternion.axisAngle(_right, -deltaY);
|
|
||||||
|
|
||||||
currentRotation = currentRotation * yawRotation * pitchRotation;
|
|
||||||
currentRotation.normalize();
|
|
||||||
|
|
||||||
_accumulatedRotationDelta = Offset.zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply zoom
|
|
||||||
if (_accumulatedZoomDelta != 0.0) {
|
|
||||||
var zoomDistance = _zoomCameraDelegate.calculateZoomDistance(
|
|
||||||
_accumulatedZoomDelta,
|
|
||||||
null,
|
|
||||||
Vector3.zero()
|
|
||||||
);
|
|
||||||
distance += zoomDistance;
|
|
||||||
distance = distance.clamp(0.1, 1000.0); // Adjust these limits as needed
|
|
||||||
|
|
||||||
_accumulatedZoomDelta = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate new position
|
|
||||||
Vector3 newPosition = _forward.clone()
|
|
||||||
..applyQuaternion(currentRotation)
|
|
||||||
..scale(-distance);
|
|
||||||
|
|
||||||
// Create and set new model matrix
|
|
||||||
Matrix4 newModelMatrix =
|
|
||||||
Matrix4.compose(newPosition, currentRotation, Vector3(1, 1, 1));
|
|
||||||
await viewer.setCameraModelMatrix4(newModelMatrix);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var modelMatrix = await viewer.getCameraModelMatrix();
|
||||||
|
Vector3 cameraPosition = modelMatrix.getTranslation();
|
||||||
|
|
||||||
|
final heightAboveSurface = getDistanceToTarget?.call(cameraPosition) ?? 1.0;
|
||||||
|
|
||||||
|
final sphereRadius = cameraPosition.length - heightAboveSurface;
|
||||||
|
|
||||||
|
// Apply rotation
|
||||||
|
if (_accumulatedRotationDelta.distanceSquared > 0) {
|
||||||
|
// Calculate the distance factor
|
||||||
|
final distanceFactor = sqrt((heightAboveSurface / sphereRadius) + 1);
|
||||||
|
|
||||||
|
// Adjust the base angle per meter
|
||||||
|
final baseAnglePerMeter = 10000 / sphereRadius;
|
||||||
|
final adjustedAnglePerMeter = baseAnglePerMeter * distanceFactor;
|
||||||
|
|
||||||
|
final metersOnSurface = _accumulatedRotationDelta;
|
||||||
|
final rotationX = metersOnSurface.dy * adjustedAnglePerMeter;
|
||||||
|
final rotationY = metersOnSurface.dx * adjustedAnglePerMeter;
|
||||||
|
|
||||||
|
Matrix4 rotation = Matrix4.rotationX(rotationX)..rotateY(rotationY);
|
||||||
|
Vector3 newPos = rotation.getRotation() * cameraPosition;
|
||||||
|
cameraPosition = newPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalize the position to maintain constant distance from center
|
||||||
|
cameraPosition =
|
||||||
|
cameraPosition.normalized() * (sphereRadius + heightAboveSurface);
|
||||||
|
|
||||||
|
// Apply zoom (modified to ensure minimum 10m distance)
|
||||||
|
if (_accumulatedZoomDelta != 0.0) {
|
||||||
|
var zoomFactor = -0.5 * _accumulatedZoomDelta;
|
||||||
|
|
||||||
|
double newHeight = heightAboveSurface * (1 - zoomFactor);
|
||||||
|
newHeight = newHeight.clamp(
|
||||||
|
10.0, double.infinity); // Prevent getting closer than 10m to surface
|
||||||
|
cameraPosition = cameraPosition.normalized() * (sphereRadius + newHeight);
|
||||||
|
|
||||||
|
_accumulatedZoomDelta = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure minimum 10m distance even after rotation
|
||||||
|
final currentHeight = cameraPosition.length - sphereRadius;
|
||||||
|
if (currentHeight < 10.0) {
|
||||||
|
cameraPosition = cameraPosition.normalized() * (sphereRadius + 10.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate view matrix (unchanged)
|
||||||
|
Vector3 forward = cameraPosition.normalized();
|
||||||
|
Vector3 up = Vector3(0, 1, 0);
|
||||||
|
final right = up.cross(forward)..normalize();
|
||||||
|
up = forward.cross(right);
|
||||||
|
|
||||||
|
Matrix4 viewMatrix = makeViewMatrix(cameraPosition, Vector3.zero(), up);
|
||||||
|
viewMatrix.invert();
|
||||||
|
|
||||||
|
// Set the camera model matrix
|
||||||
|
await viewer.setCameraModelMatrix4(viewMatrix);
|
||||||
|
_accumulatedRotationDelta = Offset.zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onKeyRelease(PhysicalKeyboardKey key) async {
|
Future<void> onKeyRelease(PhysicalKeyboardKey key) async {
|
||||||
//ignore
|
// Ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onKeypress(PhysicalKeyboardKey key) async {
|
Future<void> onKeypress(PhysicalKeyboardKey key) async {
|
||||||
//ignore
|
// Ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ import 'package:vector_math/vector_math_64.dart';
|
|||||||
|
|
||||||
class FreeFlightCameraDelegate implements CameraDelegate {
|
class FreeFlightCameraDelegate implements CameraDelegate {
|
||||||
final ThermionViewer viewer;
|
final ThermionViewer viewer;
|
||||||
final bool lockPitch;
|
|
||||||
final bool lockYaw;
|
|
||||||
final bool lockRoll;
|
final bool lockRoll;
|
||||||
final Vector3? minBounds;
|
final Vector3? minBounds;
|
||||||
final Vector3? maxBounds;
|
final Vector3? maxBounds;
|
||||||
@@ -36,8 +34,7 @@ class FreeFlightCameraDelegate implements CameraDelegate {
|
|||||||
|
|
||||||
FreeFlightCameraDelegate(
|
FreeFlightCameraDelegate(
|
||||||
this.viewer, {
|
this.viewer, {
|
||||||
this.lockPitch = false,
|
|
||||||
this.lockYaw = false,
|
|
||||||
this.lockRoll = false,
|
this.lockRoll = false,
|
||||||
this.minBounds,
|
this.minBounds,
|
||||||
this.maxBounds,
|
this.maxBounds,
|
||||||
@@ -76,9 +73,9 @@ class FreeFlightCameraDelegate implements CameraDelegate {
|
|||||||
|
|
||||||
// Apply rotation
|
// Apply rotation
|
||||||
if (_accumulatedRotation != Offset.zero) {
|
if (_accumulatedRotation != Offset.zero) {
|
||||||
double deltaX = lockYaw ? 0 : _accumulatedRotation.dx * rotationSensitivity * viewer.pixelRatio;
|
double deltaX = _accumulatedRotation.dx * rotationSensitivity * viewer.pixelRatio;
|
||||||
double deltaY = lockPitch ? 0 : _accumulatedRotation.dy * rotationSensitivity * viewer.pixelRatio;
|
double deltaY = _accumulatedRotation.dy * rotationSensitivity * viewer.pixelRatio;
|
||||||
double deltaZ = lockRoll ? 0 : (_accumulatedRotation.dx + _accumulatedRotation.dy) * rotationSensitivity * 0.5 * viewer.pixelRatio;
|
double deltaZ = (_accumulatedRotation.dx + _accumulatedRotation.dy) * rotationSensitivity * 0.5 * viewer.pixelRatio;
|
||||||
|
|
||||||
Quaternion yawRotation = Quaternion.axisAngle(_up, -deltaX);
|
Quaternion yawRotation = Quaternion.axisAngle(_up, -deltaX);
|
||||||
Quaternion pitchRotation = Quaternion.axisAngle(_right, -deltaY);
|
Quaternion pitchRotation = Quaternion.axisAngle(_right, -deltaY);
|
||||||
@@ -150,7 +147,7 @@ class FreeFlightCameraDelegate implements CameraDelegate {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> zoom(double scrollDelta, Vector2? velocity) async {
|
Future<void> zoom(double scrollDelta, Vector2? velocity) async {
|
||||||
_accumulatedZoom += scrollDelta;
|
_accumulatedZoom -= scrollDelta;
|
||||||
_lastVelocity = velocity;
|
_lastVelocity = velocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user