void QgsCameraController::onPositionChanged( Qt3DInput::QMouseEvent *mouse ) { int dx = mouse->x() - mMousePos.x(); int dy = mouse->y() - mMousePos.y(); bool hasShift = ( mouse->modifiers() & Qt::ShiftModifier ); bool hasCtrl = ( mouse->modifiers() & Qt::ControlModifier ); bool hasLeftButton = ( mouse->buttons() & Qt::LeftButton ); bool hasMiddleButton = ( mouse->buttons() & Qt::MiddleButton ); bool hasRightButton = ( mouse->buttons() & Qt::RightButton ); if ( ( hasLeftButton && hasShift && !hasCtrl ) || ( hasMiddleButton && !hasShift && !hasCtrl ) ) { // rotate/tilt using mouse (camera moves as it rotates around its view center) float pitch = mCameraPose.pitchAngle(); float yaw = mCameraPose.headingAngle(); pitch += dy; yaw -= dx / 2; mCameraPose.setPitchAngle( pitch ); mCameraPose.setHeadingAngle( yaw ); updateCameraFromPose(); } else if ( hasLeftButton && hasCtrl && !hasShift ) { // rotate/tilt using mouse (camera stays at one position as it rotates) float diffPitch = 0.2f * dy; float diffYaw = 0.2f * -dx / 2; rotateCamera( diffPitch, diffYaw ); updateCameraFromPose( true ); } else if ( hasLeftButton && !hasShift && !hasCtrl ) { // translation works as if one grabbed a point on the plane and dragged it // i.e. find out x,z of the previous mouse point, find out x,z of the current mouse point // and use the difference float z = mLastPressedHeight; QPointF p1 = screen_point_to_point_on_plane( QPointF( mMousePos.x(), mMousePos.y() ), mViewport, mCamera, z ); QPointF p2 = screen_point_to_point_on_plane( QPointF( mouse->x(), mouse->y() ), mViewport, mCamera, z ); QgsVector3D center = mCameraPose.centerPoint(); center.set( center.x() - ( p2.x() - p1.x() ), center.y(), center.z() - ( p2.y() - p1.y() ) ); mCameraPose.setCenterPoint( center ); updateCameraFromPose( true ); } else if ( hasRightButton && !hasShift && !hasCtrl ) { // zoom in/out float dist = mCameraPose.distanceFromCenterPoint(); dist -= dist * dy * 0.01f; mCameraPose.setDistanceFromCenterPoint( dist ); updateCameraFromPose(); } mMousePos = QPoint( mouse->x(), mouse->y() ); }
QgsVector3D Qgs3DUtils::mapToWorldCoordinates( const QgsVector3D &mapCoords, const QgsVector3D &origin ) { return QgsVector3D( mapCoords.x() - origin.x(), mapCoords.z() - origin.z(), -( mapCoords.y() - origin.y() ) ); }
void QgsCameraController::onKeyPressed( Qt3DInput::QKeyEvent *event ) { bool hasShift = ( event->modifiers() & Qt::ShiftModifier ); bool hasCtrl = ( event->modifiers() & Qt::ControlModifier ); int tx = 0, ty = 0, tElev = 0; switch ( event->key() ) { case Qt::Key_Left: tx -= 1; break; case Qt::Key_Right: tx += 1; break; case Qt::Key_Up: ty += 1; break; case Qt::Key_Down: ty -= 1; break; case Qt::Key_PageDown: tElev -= 1; break; case Qt::Key_PageUp: tElev += 1; break; } if ( tx || ty ) { if ( !hasShift && !hasCtrl ) { float yaw = mCameraPose.headingAngle(); float dist = mCameraPose.distanceFromCenterPoint(); float x = tx * dist * 0.02f; float y = -ty * dist * 0.02f; // moving with keyboard - take into account yaw of camera float t = sqrt( x * x + y * y ); float a = atan2( y, x ) - yaw * M_PI / 180; float dx = cos( a ) * t; float dy = sin( a ) * t; QgsVector3D center = mCameraPose.centerPoint(); center.set( center.x() + dx, center.y(), center.z() + dy ); mCameraPose.setCenterPoint( center ); updateCameraFromPose( true ); } else if ( hasShift && !hasCtrl ) { // rotate/tilt using keyboard (camera moves as it rotates around its view center) float pitch = mCameraPose.pitchAngle(); float yaw = mCameraPose.headingAngle(); pitch -= ty; // down key = moving camera toward terrain yaw -= tx; // right key = moving camera clockwise mCameraPose.setPitchAngle( pitch ); mCameraPose.setHeadingAngle( yaw ); updateCameraFromPose(); } else if ( hasCtrl && !hasShift ) { // rotate/tilt using keyboard (camera stays at one position as it rotates) float diffPitch = ty; // down key = rotating camera down float diffYaw = -tx; // right key = rotating camera to the right rotateCamera( diffPitch, diffYaw ); updateCameraFromPose( true ); } } if ( tElev ) { QgsVector3D center = mCameraPose.centerPoint(); center.set( center.x(), center.y() + tElev * 10, center.z() ); mCameraPose.setCenterPoint( center ); updateCameraFromPose( true ); } }
QgsVector3D Qgs3DUtils::worldToMapCoordinates( const QgsVector3D &worldCoords, const QgsVector3D &origin ) { return QgsVector3D( worldCoords.x() + origin.x(), -worldCoords.z() + origin.y(), worldCoords.y() + origin.z() ); }