feat: free flight camera improvements

This commit is contained in:
Nick Fisher
2024-11-19 16:30:35 +08:00
parent 9d3f87218e
commit 1ce5bd3bcf

View File

@@ -15,10 +15,6 @@ class FreeFlightInputHandlerDelegate implements InputHandlerDelegate {
final double panSensitivity; final double panSensitivity;
final double? clampY; final double? clampY;
static final _up = Vector3(0, 1, 0);
static final _forward = Vector3(0, 0, -1);
static final Vector3 _right = Vector3(1, 0, 0);
Vector2 _queuedRotationDelta = Vector2.zero(); Vector2 _queuedRotationDelta = Vector2.zero();
Vector3 _queuedTranslateDelta = Vector3.zero(); Vector3 _queuedTranslateDelta = Vector3.zero();
double _queuedZoomDelta = 0.0; double _queuedZoomDelta = 0.0;
@@ -82,54 +78,42 @@ class FreeFlightInputHandlerDelegate implements InputHandlerDelegate {
final activeCamera = await viewer.getActiveCamera(); final activeCamera = await viewer.getActiveCamera();
Matrix4 currentTransform = await viewer.getLocalTransform(await entity); Matrix4 current = await viewer.getLocalTransform(await entity);
Quaternion currentRotation =
Quaternion.fromRotation(currentTransform.getRotation());
// Calculate relative transform
Matrix4 relativeTransform = Matrix4.identity();
Vector3 relativeTranslation = Vector3.zero(); Vector3 relativeTranslation = Vector3.zero();
Quaternion relativeRotation = Quaternion.identity(); Quaternion relativeRotation = Quaternion.identity();
// Apply rotation
if (_queuedRotationDelta.length2 > 0.0) { if (_queuedRotationDelta.length2 > 0.0) {
double deltaX = _queuedRotationDelta.x * rotationSensitivity; double deltaX = _queuedRotationDelta.x * rotationSensitivity;
double deltaY = _queuedRotationDelta.y * rotationSensitivity; double deltaY = _queuedRotationDelta.y * rotationSensitivity;
relativeRotation = Quaternion.axisAngle(current.up, -deltaX) * Quaternion.axisAngle(current.right, -deltaY);
Quaternion yawRotation = Quaternion.axisAngle(_up, -deltaX);
Quaternion pitchRotation = Quaternion.axisAngle(_right, -deltaY);
relativeRotation = pitchRotation * yawRotation;
_queuedRotationDelta = Vector2.zero(); _queuedRotationDelta = Vector2.zero();
} }
// Apply pan // Apply (mouse) pan
if (_queuedTranslateDelta.length2 > 0.0) { if (_queuedTranslateDelta.length2 > 0.0) {
double deltaX = _queuedTranslateDelta.x * panSensitivity; double deltaX = _queuedTranslateDelta.x * panSensitivity;
double deltaY = _queuedTranslateDelta.y * panSensitivity; double deltaY = _queuedTranslateDelta.y * panSensitivity;
double deltaZ = -_queuedTranslateDelta.z * panSensitivity; double deltaZ = -_queuedTranslateDelta.z * panSensitivity;
relativeTranslation += _right * deltaX + _up * deltaY + _forward * deltaZ; relativeTranslation += current.right * deltaX +
current.up * deltaY +
current.forward * deltaZ;
_queuedTranslateDelta = Vector3.zero(); _queuedTranslateDelta = Vector3.zero();
} }
// Apply zoom // Apply zoom
if (_queuedZoomDelta != 0.0) { if (_queuedZoomDelta != 0.0) {
Vector3 forward = _forward.clone()..applyQuaternion(currentRotation); relativeTranslation += current.forward
relativeTranslation += forward * -_queuedZoomDelta * zoomSensitivity; ..scaled(_queuedZoomDelta * zoomSensitivity);
_queuedZoomDelta = 0.0; _queuedZoomDelta = 0.0;
} }
// Apply queued movement // Apply queued movement
if (_queuedMoveDelta.length2 > 0.0) { if (_queuedMoveDelta.length2 > 0.0) {
Vector3 forward = _forward.clone()..applyQuaternion(currentRotation); relativeTranslation += (current.right * _queuedMoveDelta.x +
Vector3 right = _right.clone()..applyQuaternion(currentRotation); current.up * _queuedMoveDelta.y +
Vector3 up = _up.clone()..applyQuaternion(currentRotation); current.forward * _queuedMoveDelta.z) *
relativeTranslation += (right * _queuedMoveDelta.x +
up * _queuedMoveDelta.y +
forward * _queuedMoveDelta.z) *
movementSensitivity; movementSensitivity;
_queuedMoveDelta = Vector3.zero(); _queuedMoveDelta = Vector3.zero();
@@ -142,23 +126,11 @@ class FreeFlightInputHandlerDelegate implements InputHandlerDelegate {
relativeTranslation = modelMatrix.getRotation() * relativeTranslation; relativeTranslation = modelMatrix.getRotation() * relativeTranslation;
} }
// Compose relative transform await viewer.setTransform(
relativeTransform = Matrix4.compose( await entity,
relativeTranslation, relativeRotation, Vector3(1, 1, 1));
// Apply relative transform to current transform Matrix4.compose(
Matrix4 newTransform = currentTransform * relativeTransform; relativeTranslation, relativeRotation, Vector3(1, 1, 1)) * current );
// Extract new position and constrain it
Vector3 newPosition = newTransform.getTranslation();
newPosition = _constrainPosition(newPosition);
// Recompose final transform with constrained position
Matrix4 finalTransform = Matrix4.compose(newPosition,
Quaternion.fromRotation(newTransform.getRotation()), Vector3(1, 1, 1));
// Update camera
await viewer.setTransform(await entity, finalTransform);
_executing = false; _executing = false;
} }