24#include <QDomDocument>
25#include <Qt3DRender/QCamera>
33 , mCamera( scene->engine()->camera() )
35 , mMouseHandler( new
Qt3DInput::QMouseHandler )
36 , mKeyboardHandler( new
Qt3DInput::QKeyboardHandler )
38 mMouseHandler->setSourceDevice(
new Qt3DInput::QMouseDevice() );
39 connect( mMouseHandler, &Qt3DInput::QMouseHandler::positionChanged,
40 this, &QgsCameraController::onPositionChanged );
41 connect( mMouseHandler, &Qt3DInput::QMouseHandler::wheel,
42 this, &QgsCameraController::onWheel );
43 connect( mMouseHandler, &Qt3DInput::QMouseHandler::pressed,
44 this, &QgsCameraController::onMousePressed );
45 connect( mMouseHandler, &Qt3DInput::QMouseHandler::released,
46 this, &QgsCameraController::onMouseReleased );
47 addComponent( mMouseHandler );
49 mKeyboardHandler->setSourceDevice(
new Qt3DInput::QKeyboardDevice() );
50 connect( mKeyboardHandler, &Qt3DInput::QKeyboardHandler::pressed,
51 this, &QgsCameraController::onKeyPressed );
52 connect( mKeyboardHandler, &Qt3DInput::QKeyboardHandler::released,
53 this, &QgsCameraController::onKeyReleased );
54 addComponent( mKeyboardHandler );
57 connect(
this, &Qt3DCore::QEntity::enabledChanged,
58 mMouseHandler, &Qt3DInput::QMouseHandler::setEnabled );
59 connect(
this, &Qt3DCore::QEntity::enabledChanged,
60 mKeyboardHandler, &Qt3DInput::QKeyboardHandler::setEnabled );
62 mFpsNavTimer =
new QTimer(
this );
63 mFpsNavTimer->setInterval( 10 );
64 connect( mFpsNavTimer, &QTimer::timeout,
this, &QgsCameraController::applyFlyModeKeyMovements );
65 mFpsNavTimer->start();
70QWindow *QgsCameraController::window()
const
73 return windowEngine ? windowEngine->
window() :
nullptr;
78 if ( navigationMode == mCameraNavigationMode )
81 mCameraNavigationMode = navigationMode;
82 mIgnoreNextMouseMove =
true;
88 if ( movementSpeed == mCameraMovementSpeed )
93 mCameraMovementSpeed = std::clamp( movementSpeed, 0.05, 150.0 );
99 mVerticalAxisInversion = inversion;
107 if (
pitch + diffPitch > 180 )
108 diffPitch = 180 -
pitch;
109 if (
pitch + diffPitch < 0 )
110 diffPitch = 0 -
pitch;
117 const QQuaternion q = QQuaternion::fromEulerAngles(
pitch + diffPitch,
yaw + diffYaw, 0 ) *
118 QQuaternion::fromEulerAngles(
pitch,
yaw, 0 ).conjugated();
121 const QVector3D position = mCamera->position();
122 QVector3D viewCenter = mCamera->viewCenter();
123 const QVector3D viewVector = viewCenter - position;
124 const QVector3D cameraToCenter = q * viewVector;
125 viewCenter = position + cameraToCenter;
130 updateCameraFromPose();
156 mCamera->setNearPlane(
distance / 2 );
157 mCamera->setFarPlane(
distance * 2 );
179 if ( camPose == mCameraPose )
182 mCameraPose = camPose;
183 updateCameraFromPose();
188 QDomElement elemCamera = doc.createElement( QStringLiteral(
"camera" ) );
189 elemCamera.setAttribute( QStringLiteral(
"x" ), mCameraPose.
centerPoint().
x() );
190 elemCamera.setAttribute( QStringLiteral(
"y" ), mCameraPose.
centerPoint().
z() );
191 elemCamera.setAttribute( QStringLiteral(
"elev" ), mCameraPose.
centerPoint().
y() );
193 elemCamera.setAttribute( QStringLiteral(
"pitch" ), mCameraPose.
pitchAngle() );
194 elemCamera.setAttribute( QStringLiteral(
"yaw" ), mCameraPose.
headingAngle() );
200 const float x = elem.attribute( QStringLiteral(
"x" ) ).toFloat();
201 const float y = elem.attribute( QStringLiteral(
"y" ) ).toFloat();
202 const float elev = elem.attribute( QStringLiteral(
"elev" ) ).toFloat();
203 const float dist = elem.attribute( QStringLiteral(
"dist" ) ).toFloat();
204 const float pitch = elem.attribute( QStringLiteral(
"pitch" ) ).toFloat();
205 const float yaw = elem.attribute( QStringLiteral(
"yaw" ) ).toFloat();
209double QgsCameraController::sampleDepthBuffer(
const QImage &buffer,
int px,
int py )
214 for (
int x = px - 3; x <= px + 3; ++x )
216 for (
int y = py - 3; y <= py + 3; ++y )
218 if ( buffer.valid( x, y ) )
230 int samplesCount = 0;
231 for (
int x = 0; x < buffer.width(); ++x )
233 for (
int y = 0; y < buffer.height(); ++y )
245 if ( samplesCount == 0 )
248 depth /= samplesCount;
253void QgsCameraController::updateCameraFromPose()
261void QgsCameraController::moveCameraPositionBy(
const QVector3D &posDiff )
264 updateCameraFromPose();
267void QgsCameraController::onPositionChanged( Qt3DInput::QMouseEvent *mouse )
269 switch ( mCameraNavigationMode )
272 onPositionChangedTerrainNavigation( mouse );
276 onPositionChangedFlyNavigation( mouse );
281bool QgsCameraController::screenPointToWorldPos( QPoint position, Qt3DRender::QCamera *mCameraBefore,
double &depth, QVector3D &worldPosition )
283 depth = sampleDepthBuffer( mDepthBufferImage, position.x(), position.y() );
284 if ( !std::isfinite( depth ) )
286 QgsDebugMsgLevel( QStringLiteral(
"screenPointToWorldPos: depth is NaN or Inf. This should not happen." ), 2 );
292 if ( !std::isfinite( worldPosition.x() ) || !std::isfinite( worldPosition.y() ) || !std::isfinite( worldPosition.z() ) )
294 QgsDebugMsgLevel( QStringLiteral(
"screenPointToWorldPos: position is NaN or Inf. This should not happen." ), 2 );
304void QgsCameraController::onPositionChangedTerrainNavigation( Qt3DInput::QMouseEvent *mouse )
306 if ( mIgnoreNextMouseMove )
308 mIgnoreNextMouseMove =
false;
309 mMousePos = QPoint( mouse->x(), mouse->y() );
313 const int dx = mouse->x() - mMousePos.x();
314 const int dy = mouse->y() - mMousePos.y();
316 const bool hasShift = ( mouse->modifiers() & Qt::ShiftModifier );
317 const bool hasCtrl = ( mouse->modifiers() & Qt::ControlModifier );
318 const bool hasLeftButton = ( mouse->buttons() & Qt::LeftButton );
319 const bool hasMiddleButton = ( mouse->buttons() & Qt::MiddleButton );
320 const bool hasRightButton = ( mouse->buttons() & Qt::RightButton );
322 if ( ( hasLeftButton && hasShift && !hasCtrl ) || ( hasMiddleButton && !hasShift && !hasCtrl ) )
325 setMouseParameters( MouseOperation::RotationCenter, mMousePos );
327 float scale =
static_cast<float>( std::max( mScene->
engine()->
size().width(), mScene->
engine()->
size().height() ) );
328 float pitchDiff = 180.0f *
static_cast<float>( mouse->y() - mClickPoint.y() ) / scale;
329 float yawDiff = -180.0f *
static_cast<float>( mouse->x() - mClickPoint.x() ) / scale;
331 if ( !mDepthBufferIsReady )
334 if ( !mRotationCenterCalculated )
337 QVector3D worldPosition;
338 if ( screenPointToWorldPos( mClickPoint, mCameraBefore.get(), depth, worldPosition ) )
340 mRotationCenter = worldPosition;
341 mRotationDistanceFromCenter = ( mRotationCenter - mCameraBefore->position() ).length();
343 mRotationCenterCalculated =
true;
349 QVector3D shiftVector = mRotationCenter - mCamera->viewCenter();
351 QVector3D newViewCenterWorld =
camera()->viewCenter() + shiftVector;
352 QVector3D newCameraPosition =
camera()->position() + shiftVector;
358 updateCameraFromPose();
366 QVector3D clickedPositionWorld = ray.
origin() + mRotationDistanceFromCenter * ray.
direction();
368 QVector3D shiftVector = clickedPositionWorld - mCamera->viewCenter();
370 QVector3D newViewCenterWorld =
camera()->viewCenter() - shiftVector;
371 QVector3D newCameraPosition =
camera()->position() - shiftVector;
375 updateCameraFromPose();
378 else if ( hasLeftButton && hasCtrl && !hasShift )
380 setMouseParameters( MouseOperation::RotationCamera );
382 const float diffPitch = 0.2f * dy;
383 const float diffYaw = - 0.2f * dx;
386 else if ( hasLeftButton && !hasShift && !hasCtrl )
389 setMouseParameters( MouseOperation::Translation, mMousePos );
391 if ( !mDepthBufferIsReady )
394 if ( !mDragPointCalculated )
397 QVector3D worldPosition;
398 if ( screenPointToWorldPos( mClickPoint, mCameraBefore.get(), depth, worldPosition ) )
401 mDragPoint = worldPosition;
402 mDragPointCalculated =
true;
407 QVector3D cameraBeforeDragPos = mCameraBefore->position();
410 QVector3D cameraBeforeToMoveToPos = ( moveToPosition - mCameraBefore->position() ).normalized();
411 QVector3D cameraBeforeToDragPointPos = ( mDragPoint - mCameraBefore->position() ).normalized();
414 if ( cameraBeforeToMoveToPos.y() == 0 )
416 cameraBeforeToMoveToPos.setY( 0.01 );
417 cameraBeforeToMoveToPos = cameraBeforeToMoveToPos.normalized();
420 if ( cameraBeforeToDragPointPos.y() == 0 )
422 cameraBeforeToDragPointPos.setY( 0.01 );
423 cameraBeforeToDragPointPos = cameraBeforeToDragPointPos.normalized();
426 double d1 = ( mDragPoint.y() - cameraBeforeDragPos.y() ) / cameraBeforeToMoveToPos.y();
427 double d2 = ( mDragPoint.y() - cameraBeforeDragPos.y() ) / cameraBeforeToDragPointPos.y();
429 QVector3D from = cameraBeforeDragPos + d1 * cameraBeforeToMoveToPos;
430 QVector3D to = cameraBeforeDragPos + d2 * cameraBeforeToDragPointPos;
432 QVector3D shiftVector = to - from;
434 mCameraPose.
setCenterPoint( mCameraBefore->viewCenter() + shiftVector );
435 updateCameraFromPose();
437 else if ( hasLeftButton && hasShift && hasCtrl )
441 double tElev = mMousePos.y() - mouse->y();
442 center.
set( center.
x(), center.
y() + tElev * 0.5, center.
z() );
444 updateCameraFromPose();
446 else if ( hasRightButton && !hasShift && !hasCtrl )
448 setMouseParameters( MouseOperation::Zoom, mMousePos );
449 if ( !mDepthBufferIsReady )
452 if ( !mDragPointCalculated )
455 QVector3D worldPosition;
456 if ( screenPointToWorldPos( mClickPoint, mCameraBefore.get(), depth, worldPosition ) )
458 mDragPoint = worldPosition;
459 mDragPointCalculated =
true;
463 float dist = ( mCameraBefore->position() - mDragPoint ).length();
466 int screenHeight = mScene->
engine()->
size().height();
467 QWindow *win = window();
470 yOffset = win->mapToGlobal( QPoint( 0, 0 ) ).y();
471 screenHeight = win->screen()->size().height();
475 if ( mMousePos.y() > mClickPoint.y() )
477 double f = ( double )( mMousePos.y() - mClickPoint.y() ) / (
double )( screenHeight - mClickPoint.y() - yOffset );
478 f = std::max( 0.0, std::min( 1.0, f ) );
479 f = 1 - ( std::expm1( -2 * f ) ) / ( std::expm1( -2 ) );
484 double f = 1 - ( double )( mMousePos.y() + yOffset ) / (
double )( mClickPoint.y() + yOffset );
485 f = std::max( 0.0, std::min( 1.0, f ) );
486 f = ( std::expm1( 2 * f ) ) / ( std::expm1( 2 ) );
487 dist = dist + 2 * dist * f;
492 QVector3D shiftVector = mDragPoint - mCamera->viewCenter();
494 QVector3D newViewCenterWorld =
camera()->viewCenter() + shiftVector;
498 updateCameraFromPose();
504 QVector3D clickedPositionWorld = ray.
origin() + dist * ray.
direction();
506 QVector3D shiftVector = clickedPositionWorld - mCamera->viewCenter();
508 QVector3D newViewCenterWorld =
camera()->viewCenter() - shiftVector;
509 QVector3D newCameraPosition =
camera()->position() - shiftVector;
513 updateCameraFromPose();
517 mMousePos = QPoint( mouse->x(), mouse->y() );
524 dist -= dist * factor * 0.01f;
526 updateCameraFromPose();
529void QgsCameraController::handleTerrainNavigationWheelZoom()
531 if ( !mDepthBufferIsReady )
534 if ( !mZoomPointCalculated )
537 QVector3D worldPosition;
538 if ( screenPointToWorldPos( mMousePos, mCameraBefore.get(), depth, worldPosition ) )
540 mZoomPoint = worldPosition;
541 mZoomPointCalculated =
true;
545 float f = mCumulatedWheelY / ( 120.0 * 24.0 );
547 double dist = ( mZoomPoint - mCameraBefore->position() ).length();
552 QVector3D shiftVector = mZoomPoint - mCamera->viewCenter();
554 QVector3D newViewCenterWorld =
camera()->viewCenter() + shiftVector;
558 updateCameraFromPose();
564 QVector3D clickedPositionWorld = ray.
origin() + dist * ray.
direction();
566 QVector3D shiftVector = clickedPositionWorld - mCamera->viewCenter();
568 QVector3D newViewCenterWorld =
camera()->viewCenter() - shiftVector;
569 QVector3D newCameraPosition =
camera()->position() - shiftVector;
573 updateCameraFromPose();
575 mCumulatedWheelY = 0;
576 setMouseParameters( MouseOperation::None );
579void QgsCameraController::onWheel( Qt3DInput::QWheelEvent *wheel )
581 switch ( mCameraNavigationMode )
585 const float scaling = ( ( wheel->modifiers() & Qt::ControlModifier ) != 0 ? 0.1f : 1.0f ) / 1000.f;
586 setCameraMovementSpeed( mCameraMovementSpeed + mCameraMovementSpeed * scaling * wheel->angleDelta().y() );
593 const float scaling = ( ( wheel->modifiers() & Qt::ControlModifier ) != 0 ? 0.5f : 5.f );
597 mCumulatedWheelY += scaling * wheel->angleDelta().y();
599 if ( mCurrentOperation != MouseOperation::ZoomWheel )
601 setMouseParameters( MouseOperation::ZoomWheel );
605 handleTerrainNavigationWheelZoom();
612void QgsCameraController::onMousePressed( Qt3DInput::QMouseEvent *mouse )
614 mKeyboardHandler->setFocus(
true );
616 if ( mouse->button() == Qt3DInput::QMouseEvent::MiddleButton ||
617 ( ( mouse->modifiers() & Qt::ShiftModifier ) != 0 && mouse->button() == Qt3DInput::QMouseEvent::LeftButton ) ||
618 ( ( mouse->modifiers() & Qt::ControlModifier ) != 0 && mouse->button() == Qt3DInput::QMouseEvent::LeftButton ) )
620 mMousePos = QPoint( mouse->x(), mouse->y() );
622 if ( mCaptureFpsMouseMovements )
623 mIgnoreNextMouseMove =
true;
625 const MouseOperation operation
627 ( mouse->modifiers() & Qt::ControlModifier ) != 0 && mouse->button() == Qt3DInput::QMouseEvent::LeftButton ?
628 MouseOperation::RotationCamera :
629 MouseOperation::RotationCenter
631 setMouseParameters( operation, mMousePos );
634 else if ( mouse->button() == Qt3DInput::QMouseEvent::LeftButton || mouse->button() == Qt3DInput::QMouseEvent::RightButton )
636 mMousePos = QPoint( mouse->x(), mouse->y() );
638 if ( mCaptureFpsMouseMovements )
639 mIgnoreNextMouseMove =
true;
641 const MouseOperation operation = ( mouse->button() == Qt3DInput::QMouseEvent::LeftButton ) ? MouseOperation::Translation : MouseOperation::Zoom;
642 setMouseParameters( operation, mMousePos );
646void QgsCameraController::onMouseReleased( Qt3DInput::QMouseEvent *mouse )
650 setMouseParameters( MouseOperation::None );
653void QgsCameraController::onKeyPressed( Qt3DInput::QKeyEvent *event )
655 if ( event->modifiers() & Qt::ControlModifier && event->key() == Qt::Key_QuoteLeft )
658 switch ( mCameraNavigationMode )
670 switch ( mCameraNavigationMode )
674 onKeyPressedFlyNavigation( event );
680 onKeyPressedTerrainNavigation( event );
686void QgsCameraController::onKeyPressedTerrainNavigation( Qt3DInput::QKeyEvent *event )
688 const bool hasShift = (
event->modifiers() & Qt::ShiftModifier );
689 const bool hasCtrl = (
event->modifiers() & Qt::ControlModifier );
691 int tx = 0, ty = 0, tElev = 0;
692 switch ( event->key() )
708 case Qt::Key_PageDown:
718 if ( !hasShift && !hasCtrl )
722 else if ( hasShift && !hasCtrl )
728 else if ( hasCtrl && !hasShift )
731 const float diffPitch = ty;
732 const float diffYaw = -tx;
740 center.
set( center.
x(), center.
y() + tElev * 10, center.
z() );
742 updateCameraFromPose();
746void QgsCameraController::onKeyPressedFlyNavigation( Qt3DInput::QKeyEvent *event )
748 switch ( event->key() )
750 case Qt::Key_QuoteLeft:
753 mCaptureFpsMouseMovements = !mCaptureFpsMouseMovements;
754 mIgnoreNextMouseMove =
true;
755 if ( mCaptureFpsMouseMovements )
757 qApp->setOverrideCursor( QCursor( Qt::BlankCursor ) );
761 qApp->restoreOverrideCursor();
769 if ( mCaptureFpsMouseMovements )
771 mCaptureFpsMouseMovements =
false;
772 mIgnoreNextMouseMove =
true;
773 qApp->restoreOverrideCursor();
783 if ( event->isAutoRepeat() )
786 mDepressedKeys.insert( event->key() );
791 const QVector3D cameraUp = mCamera->upVector().normalized();
793 const QVector3D cameraLeft = QVector3D::crossProduct( cameraUp, cameraFront );
795 QVector3D cameraPosDiff( 0.0f, 0.0f, 0.0f );
799 cameraPosDiff += tx * cameraFront;
803 cameraPosDiff += ty * cameraLeft;
807 cameraPosDiff += tz * QVector3D( 0.0f, 1.0f, 0.0f );
810 moveCameraPositionBy( cameraPosDiff );
813void QgsCameraController::applyFlyModeKeyMovements()
816 const bool shiftPressed = mDepressedKeys.contains( Qt::Key_Shift );
817 const bool ctrlPressed = mDepressedKeys.contains( Qt::Key_Control );
819 const double movementSpeed = mCameraMovementSpeed * ( shiftPressed ? 2 : 1 ) * ( ctrlPressed ? 0.1 : 1 );
821 bool changed =
false;
825 if ( mDepressedKeys.contains( Qt::Key_Left ) || mDepressedKeys.contains( Qt::Key_A ) )
831 if ( mDepressedKeys.contains( Qt::Key_Right ) || mDepressedKeys.contains( Qt::Key_D ) )
837 if ( mDepressedKeys.contains( Qt::Key_Up ) || mDepressedKeys.contains( Qt::Key_W ) )
843 if ( mDepressedKeys.contains( Qt::Key_Down ) || mDepressedKeys.contains( Qt::Key_S ) )
851 static constexpr double ELEVATION_MOVEMENT_SCALE = 0.5;
852 if ( mDepressedKeys.contains( Qt::Key_PageUp ) || mDepressedKeys.contains( Qt::Key_E ) )
855 z += ELEVATION_MOVEMENT_SCALE * movementSpeed;
858 if ( mDepressedKeys.contains( Qt::Key_PageDown ) || mDepressedKeys.contains( Qt::Key_Q ) )
861 z -= ELEVATION_MOVEMENT_SCALE * movementSpeed;
868void QgsCameraController::onPositionChangedFlyNavigation( Qt3DInput::QMouseEvent *mouse )
870 const bool hasMiddleButton = ( mouse->buttons() & Qt::MiddleButton );
871 const bool hasRightButton = ( mouse->buttons() & Qt::RightButton );
873 const double dx = mCaptureFpsMouseMovements ? QCursor::pos().x() - mMousePos.x() : mouse->x() - mMousePos.x();
874 const double dy = mCaptureFpsMouseMovements ? QCursor::pos().y() - mMousePos.y() : mouse->y() - mMousePos.y();
875 mMousePos = mCaptureFpsMouseMovements ? QCursor::pos() : QPoint( mouse->x(), mouse->y() );
877 if ( mIgnoreNextMouseMove )
879 mIgnoreNextMouseMove =
false;
883 if ( hasMiddleButton )
886 const QVector3D cameraUp = mCamera->upVector().normalized();
888 const QVector3D cameraLeft = QVector3D::crossProduct( cameraUp, cameraFront );
889 const QVector3D cameraPosDiff = -dx * cameraLeft - dy * cameraUp;
890 moveCameraPositionBy( mCameraMovementSpeed * cameraPosDiff / 10.0 );
892 else if ( hasRightButton )
896 const QVector3D cameraPosDiff = dy * cameraFront;
897 moveCameraPositionBy( mCameraMovementSpeed * cameraPosDiff / 5.0 );
901 if ( mCaptureFpsMouseMovements )
903 float diffPitch = -0.2f * dy;
904 switch ( mVerticalAxisInversion )
915 const float diffYaw = - 0.2f * dx;
918 else if ( mouse->buttons() & Qt::LeftButton )
920 float diffPitch = -0.2f * dy;
921 switch ( mVerticalAxisInversion )
931 const float diffYaw = - 0.2f * dx;
936 if ( mCaptureFpsMouseMovements )
938 mIgnoreNextMouseMove =
true;
945void QgsCameraController::onKeyReleased( Qt3DInput::QKeyEvent *event )
947 if ( event->isAutoRepeat() )
950 mDepressedKeys.remove( event->key() );
959 updateCameraFromPose();
968 updateCameraFromPose();
974 updateCameraFromPose();
981 const float x = tx * dist * 0.02f;
982 const float y = -ty * dist * 0.02f;
985 const float t = sqrt( x * x + y * y );
986 const float a = atan2( y, x ) -
yaw * M_PI / 180;
987 const float dx = cos( a ) * t;
988 const float dy = sin( a ) * t;
991 center.
set( center.
x() + dx, center.
y(), center.
z() + dy );
993 updateCameraFromPose();
998 if ( event->key() == Qt::Key_QuoteLeft )
1001 switch ( mCameraNavigationMode )
1005 switch ( event->key() )
1015 case Qt::Key_PageUp:
1017 case Qt::Key_PageDown:
1021 case Qt::Key_Escape:
1022 if ( mCaptureFpsMouseMovements )
1034 switch ( event->key() )
1038 case Qt::Key_PageUp:
1039 case Qt::Key_PageDown:
1053 mDepthBufferImage = depthImage;
1054 mDepthBufferIsReady =
true;
1056 if ( mCurrentOperation == MouseOperation::ZoomWheel )
1058 handleTerrainNavigationWheelZoom();
1062bool QgsCameraController::isATranslationRotationSequence( MouseOperation newOperation )
const
1064 return std::find( mTranslateOrRotate.begin(), mTranslateOrRotate.end(), newOperation ) != std::end( mTranslateOrRotate ) &&
1065 std::find( mTranslateOrRotate.begin(), mTranslateOrRotate.end(), mCurrentOperation ) != std::end( mTranslateOrRotate );
1068void QgsCameraController::setMouseParameters(
const MouseOperation &newOperation,
const QPoint &clickPoint )
1070 if ( newOperation == mCurrentOperation )
1075 if ( newOperation == MouseOperation::None )
1077 mClickPoint = QPoint();
1085 else if ( mClickPoint.isNull() || isATranslationRotationSequence( newOperation ) )
1087 mClickPoint = clickPoint;
1091 mCurrentOperation = newOperation;
1092 mDepthBufferIsReady =
false;
1093 mRotationCenterCalculated =
false;
1094 mDragPointCalculated =
false;
1095 mZoomPointCalculated =
false;
1097 if ( mCurrentOperation != MouseOperation::None && mCurrentOperation != MouseOperation::RotationCamera )
1101 mCameraBefore->setProjectionMatrix( mCamera->projectionMatrix() );
1102 mCameraBefore->setNearPlane( mCamera->nearPlane() );
1103 mCameraBefore->setFarPlane( mCamera->farPlane() );
1104 mCameraBefore->setAspectRatio( mCamera->aspectRatio() );
1105 mCameraBefore->setFieldOfView( mCamera->fieldOfView() );
VerticalAxisInversion
Vertical axis inversion options for 3D views.
@ Always
Always invert vertical axis movements.
@ Never
Never invert vertical axis movements.
@ WhenDragging
Invert vertical axis movements when dragging in first person modes.
NavigationMode
The navigation mode used by 3D cameras.
@ TerrainBased
The default navigation based on the terrain.
@ Walk
Uses WASD keys or arrows to navigate in walking (first person) manner.
QgsAbstract3DEngine * engine() const
Returns the abstract 3D engine.
QgsTerrainEntity * terrainEntity()
Returns terrain entity (may be temporarily nullptr)
static double decodeDepth(const QRgb &pixel)
Decodes the depth value from the pixel's color value The depth value is encoded from OpenGL side (the...
static QVector3D screenPointToWorldPos(const QPoint &screenPoint, double depth, const QSize &screenSize, Qt3DRender::QCamera *camera)
Converts the clicked mouse position to the corresponding 3D world coordinates.
static QgsRay3D rayFromScreenPoint(const QPoint &point, const QSize &windowSize, Qt3DRender::QCamera *camera)
Convert from clicked point on the screen to a ray in world coordinates.
virtual QSize size() const =0
Returns size of the engine's rendering area in pixels.
void navigationModeChanged(Qgis::NavigationMode mode)
Emitted when the navigation mode is changed using the hotkey ctrl + ~.
void readXml(const QDomElement &elem)
Reads camera configuration from the given DOM element.
float pitch() const
Returns pitch angle in degrees (0 = looking from the top, 90 = looking from the side).
Qt3DRender::QCamera * camera() const
Returns camera that is being controlled.
~QgsCameraController() override
float yaw() const
Returns yaw angle in degrees.
void requestDepthBufferCapture()
Emitted to ask for the depth buffer image.
void tiltUpAroundViewCenter(float deltaPitch)
Tilt up the view by deltaPitch around the view center (camera moves)
void setVerticalAxisInversion(Qgis::VerticalAxisInversion inversion)
Sets the vertical axis inversion behavior.
bool willHandleKeyEvent(QKeyEvent *event)
Returns true if the camera controller will handle the specified key event, preventing it from being i...
float distance() const
Returns distance of the camera from the point it is looking at.
void rotateCamera(float diffPitch, float diffYaw)
Rotates the camera on itself.
void setCameraNavigationMode(Qgis::NavigationMode navigationMode)
Sets the navigation mode used by the camera controller.
void cameraChanged()
Emitted when camera has been updated.
void cameraMovementSpeedChanged(double speed)
Emitted whenever the camera movement speed is changed by the controller.
QgsCameraController(Qgs3DMapScene *scene)
Constructs the camera controller with optional parent node that will take ownership.
void frameTriggered(float dt)
Called internally from 3D scene when a new frame is generated. Updates camera according to keyboard/m...
void resetView(float distance)
Move camera back to the initial position (looking down towards origin of world's coordinates)
void setLookingAtPoint(const QgsVector3D &point, float distance, float pitch, float yaw)
Sets the complete camera configuration: the point towards it is looking (in 3D world coordinates),...
QgsVector3D lookingAtPoint() const
Returns the point in the world coordinates towards which the camera is looking.
QDomElement writeXml(QDomDocument &doc) const
Writes camera configuration to the given DOM element.
void setViewFromTop(float worldX, float worldY, float distance, float yaw=0)
Sets camera to look down towards given point in world coordinate, in given distance from plane with z...
void zoom(float factor)
Zoom the map by factor.
void rotateAroundViewCenter(float deltaYaw)
Rotate clockwise the view by deltaYaw around the view center (camera moves)
void walkView(double tx, double ty, double tz)
Walks into the map by tx, ty, and tz.
void setCameraHeadingAngle(float angle)
Set camera heading to angle (used for rotating the view)
void setCameraMovementSpeed(double movementSpeed)
Sets the camera movement speed.
void setCameraPose(const QgsCameraPose &camPose)
Sets camera pose.
void depthBufferCaptured(const QImage &depthImage)
Sets the depth buffer image used by the camera controller to calculate world position from a pixel's ...
void cameraRotationCenterChanged(QVector3D position)
Emitted when the camera rotation center changes.
void setCursorPosition(QPoint point)
Emitted when the mouse cursor position should be moved to the specified point on the map viewport.
void moveView(float tx, float ty)
Move the map by tx and ty.
float headingAngle() const
Returns heading (yaw) angle in degrees.
QgsVector3D centerPoint() const
Returns center point (towards which point the camera is looking)
float pitchAngle() const
Returns pitch angle in degrees.
float distanceFromCenterPoint() const
Returns distance of the camera from the center point.
void setPitchAngle(float pitch)
Sets pitch angle in degrees.
void setCenterPoint(const QgsVector3D &point)
Sets center point (towards which point the camera is looking)
void setHeadingAngle(float heading)
Sets heading (yaw) angle in degrees.
void setDistanceFromCenterPoint(float distance)
Sets distance of the camera from the center point.
void updateCamera(Qt3DRender::QCamera *camera)
Update Qt3D camera view matrix based on the pose.
A representation of a ray in 3D.
QVector3D origin() const
Returns the origin of the ray.
QVector3D direction() const
Returns the direction of the ray see setDirection()
Class for storage of 3D vectors similar to QVector3D, with the difference that it uses double precisi...
double y() const
Returns Y coordinate.
double z() const
Returns Z coordinate.
double x() const
Returns X coordinate.
void set(double x, double y, double z)
Sets vector coordinates.
QWindow * window()
Returns the internal 3D window where all the rendered output is displayed.
#define QgsDebugMsgLevel(str, level)