Skip to content

Commit

Permalink
Improve capturing of cursor in mouse lock mode
Browse files Browse the repository at this point in the history
- Avoid jumpy first motion after activating lock
- Fix capture of cursor to map center -- because the camera controller
has no knowledge of the map canvas geometry (specifically the window
position), we can't set the global mouse cursor position directly from
the controller and instead need to push reponsibility for this up to
the 3d map canvas widget instead
  • Loading branch information
nyalldawson committed Jan 14, 2021
1 parent 0cb2f50 commit a630ef4
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 21 deletions.
21 changes: 12 additions & 9 deletions src/3d/qgscameracontroller.cpp
Expand Up @@ -614,36 +614,41 @@ void QgsCameraController::onPositionChangedFlyNavigation( Qt3DInput::QMouseEvent

if ( mCaptureFpsMouseMovements )
{
const double dx = QCursor::pos().x() - mMousePos.x();
const double dy = QCursor::pos().y() - mMousePos.y();
mMousePos = QCursor::pos();

if ( mIgnoreNextMouseMove )
{
mIgnoreNextMouseMove = false;
return;
}

double dx = QCursor::pos().x() - mMousePos.x();
double dy = QCursor::pos().y() - mMousePos.y();
if ( mPressedButton != Qt3DInput::QMouseEvent::RightButton )
{
float diffPitch = -1 * 0.2f * dy;
float diffYaw = - 0.2f * dx;
rotateCamera( diffPitch, diffYaw );
updateCameraFromPose( false );
}

mIgnoreNextMouseMove = true;
QCursor::setPos( mViewport.width(), mViewport.height() );
mMousePos = QCursor::pos();

// reset cursor back to center of map widget
emit setCursorPosition( QPoint( mViewport.width() / 2, mViewport.height() / 2 ) );
}
else
{
const double dx = mouse->x() - mMousePos.x();
const double dy = mouse->y() - mMousePos.y();
mMousePos = QPoint( mouse->x(), mouse->y() );

if ( mIgnoreNextMouseMove )
{
mMousePos = QPoint( mouse->x(), mouse->y() );
mIgnoreNextMouseMove = false;
return;
}

double dx = mouse->x() - mMousePos.x();
double dy = mouse->y() - mMousePos.y();
if ( mPressedButton == Qt3DInput::QMouseEvent::LeftButton || mPressedButton == Qt3DInput::QMouseEvent::MiddleButton )
{
float diffPitch = 0.2f * dy;
Expand All @@ -659,8 +664,6 @@ void QgsCameraController::onPositionChangedFlyNavigation( Qt3DInput::QMouseEvent
QVector3D cameraPosDiff = dx / mViewport.width() * cameraLeft + dy / mViewport.height() * cameraUp;
moveCameraPositionBy( 5.0 * mCameraMovementSpeed * cameraPosDiff );
}

mMousePos = QPoint( mouse->x(), mouse->y() );
}
}

Expand Down
6 changes: 6 additions & 0 deletions src/3d/qgscameracontroller.h
Expand Up @@ -196,6 +196,12 @@ class _3D_EXPORT QgsCameraController : public Qt3DCore::QEntity
//! Emitted when the navigation mode is changed using the hotkey ctrl + ~
void navigationModeHotKeyPressed( QgsCameraController::NavigationMode mode );

/**
* Emitted when the mouse cursor position should be moved to the specified \a point
* on the map viewport.
*/
void setCursorPosition( QPoint point );

private slots:
void onPositionChanged( Qt3DInput::QMouseEvent *mouse );
void onWheel( Qt3DInput::QWheelEvent *wheel );
Expand Down
12 changes: 4 additions & 8 deletions src/app/3d/qgs3dmapcanvas.cpp
Expand Up @@ -113,15 +113,11 @@ void Qgs3DMapCanvas::setMap( Qgs3DMapSettings *map )
resetView();

// Connect the camera to the navigation widget.
QObject::connect(
this->cameraController(),
&QgsCameraController::cameraChanged,
mNavigationWidget,
[ = ]
connect( cameraController(), &QgsCameraController::cameraChanged, mNavigationWidget, &Qgs3DNavigationWidget::updateFromCamera );
connect( cameraController(), &QgsCameraController::setCursorPosition, this, [ = ]( QPoint point )
{
mNavigationWidget->updateFromCamera();
}
);
QCursor::setPos( mapToGlobal( point ) );
} );

emit mapSettingsChanged();
}
Expand Down
6 changes: 2 additions & 4 deletions src/app/3d/qgs3dnavigationwidget.h
Expand Up @@ -31,15 +31,13 @@ class Qgs3DNavigationWidget : public QWidget
public:
Qgs3DNavigationWidget( Qgs3DMapCanvas *parent = nullptr );

public slots:

/**
* Update the state of navigation widget from camera's state
*/
void updateFromCamera();

signals:

public slots:

private:
Qgs3DMapCanvas *mParent3DMapCanvas = nullptr;
QToolButton *mZoomInButton = nullptr;
Expand Down

0 comments on commit a630ef4

Please sign in to comment.