Skip to content
Permalink
Browse files

Use proper game style keyboard handling

Instead of just reponding to key presses/releases (and auto repeat
versions of these), instead track which keys are held down continuously
and use a timer based approach to handle the actual resultant camera
movement.

This allows use of multiple keys when navigating, e.g. moving forward
while strafing left/right/up/down.
  • Loading branch information
nyalldawson committed Jan 13, 2021
1 parent 7f3b407 commit ea5b4cb0d9b5451c76e66e3299c5be18d46becee
Showing with 53 additions and 30 deletions.
  1. +49 −29 src/3d/qgscameracontroller.cpp
  2. +4 −1 src/3d/qgscameracontroller.h
@@ -58,6 +58,11 @@ QgsCameraController::QgsCameraController( Qt3DCore::QNode *parent )
mMouseHandler, &Qt3DInput::QMouseHandler::setEnabled );
connect( this, &Qt3DCore::QEntity::enabledChanged,
mKeyboardHandler, &Qt3DInput::QMouseHandler::setEnabled );

mFpsNavTimer = new QTimer( this );
mFpsNavTimer->setInterval( 10 );
connect( mFpsNavTimer, &QTimer::timeout, this, &QgsCameraController::onKeyPressedFlyNavigation );
mFpsNavTimer->start();
}

void QgsCameraController::setCameraNavigationMode( QgsCameraController::NavigationMode navigationMode )
@@ -418,7 +423,11 @@ void QgsCameraController::onKeyPressed( Qt3DInput::QKeyEvent *event )
{
if ( mCameraNavigationMode == NavigationMode::FlyNavigation )
{
onKeyPressedFlyNavigation( event );
if ( event->isAutoRepeat() )
return;

mDepressedKeys.insert( event->key() );
onKeyPressedFlyNavigation();
return;
}

@@ -481,45 +490,53 @@ void QgsCameraController::onKeyPressed( Qt3DInput::QKeyEvent *event )
}
}

void QgsCameraController::onKeyPressedFlyNavigation( Qt3DInput::QKeyEvent *event )
void QgsCameraController::onKeyPressedFlyNavigation()
{
QVector3D cameraUp = mCamera->upVector().normalized();
QVector3D cameraFront = ( QVector3D( mCameraPose.centerPoint().x(), mCameraPose.centerPoint().y(), mCameraPose.centerPoint().z() ) - mCamera->position() ).normalized();
QVector3D cameraLeft = QVector3D::crossProduct( cameraUp, cameraFront );

QVector3D cameraPosDiff( 0.0f, 0.0f, 0.0f );

switch ( event->key() )
bool changed = false;
if ( mDepressedKeys.contains( Qt::Key_Left ) || mDepressedKeys.contains( Qt::Key_A ) )
{
case Qt::Key_Left:
case Qt::Key_A:
cameraPosDiff = mCameraMovementSpeed * cameraLeft;
break;
case Qt::Key_Right:
case Qt::Key_D:
cameraPosDiff = - mCameraMovementSpeed * cameraLeft;
break;
changed = true;
cameraPosDiff += mCameraMovementSpeed * cameraLeft;
}

case Qt::Key_Up:
case Qt::Key_W:
cameraPosDiff = mCameraMovementSpeed * cameraFront;
break;
case Qt::Key_Down:
case Qt::Key_S:
cameraPosDiff = - mCameraMovementSpeed * cameraFront;
break;
if ( mDepressedKeys.contains( Qt::Key_Right ) || mDepressedKeys.contains( Qt::Key_D ) )
{
changed = true;
cameraPosDiff += - mCameraMovementSpeed * cameraLeft;
}

case Qt::Key_PageUp:
case Qt::Key_Q:
cameraPosDiff = mCameraMovementSpeed * QVector3D( 0.0f, 1.0f, 0.0f );
break;
case Qt::Key_PageDown:
case Qt::Key_E:
cameraPosDiff = - mCameraMovementSpeed * QVector3D( 0.0f, 1.0f, 0.0f );
break;
if ( mDepressedKeys.contains( Qt::Key_Up ) || mDepressedKeys.contains( Qt::Key_W ) )
{
changed = true;
cameraPosDiff += mCameraMovementSpeed * cameraFront;
}

moveCameraPositionBy( cameraPosDiff );
if ( mDepressedKeys.contains( Qt::Key_Down ) || mDepressedKeys.contains( Qt::Key_S ) )
{
changed = true;
cameraPosDiff += - mCameraMovementSpeed * cameraFront;
}

if ( mDepressedKeys.contains( Qt::Key_PageUp ) || mDepressedKeys.contains( Qt::Key_Q ) )
{
changed = true;
cameraPosDiff += mCameraMovementSpeed * QVector3D( 0.0f, 1.0f, 0.0f );
}

if ( mDepressedKeys.contains( Qt::Key_PageDown ) || mDepressedKeys.contains( Qt::Key_E ) )
{
changed = true;
cameraPosDiff += - mCameraMovementSpeed * QVector3D( 0.0f, 1.0f, 0.0f );
}

if ( changed )
moveCameraPositionBy( cameraPosDiff );
}

void QgsCameraController::onPositionChangedFlyNavigation( Qt3DInput::QMouseEvent *mouse )
@@ -549,7 +566,10 @@ void QgsCameraController::onPositionChangedFlyNavigation( Qt3DInput::QMouseEvent

void QgsCameraController::onKeyReleased( Qt3DInput::QKeyEvent *event )
{
Q_UNUSED( event )
if ( event->isAutoRepeat() )
return;

mDepressedKeys.remove( event->key() );
}

void QgsCameraController::onPickerMousePressed( Qt3DRender::QPickEvent *pick )
@@ -203,7 +203,7 @@ class _3D_EXPORT QgsCameraController : public Qt3DCore::QEntity
void onPickerMousePressed( Qt3DRender::QPickEvent *pick );

private:
void onKeyPressedFlyNavigation( Qt3DInput::QKeyEvent *mouse );
void onKeyPressedFlyNavigation();
void onPositionChangedFlyNavigation( Qt3DInput::QMouseEvent *mouse );

private:
@@ -232,6 +232,9 @@ class _3D_EXPORT QgsCameraController : public Qt3DCore::QEntity
Qt3DInput::QKeyboardHandler *mKeyboardHandler = nullptr;
NavigationMode mCameraNavigationMode = NavigationMode::TerrainBasedNavigation;
double mCameraMovementSpeed = 5.0;

QSet< int > mDepressedKeys;
QTimer *mFpsNavTimer = nullptr;
};

#endif // QGSCAMERACONTROLLER_H

0 comments on commit ea5b4cb

Please sign in to comment.
You can’t perform that action at this time.