24#include <QDomDocument>
25#include <Qt3DRender/QCamera>
33 , mCamera( scene->engine()->camera() )
34 , mCameraBeforeRotation( new
Qt3DRender::QCamera )
37 , mMouseHandler( new
Qt3DInput::QMouseHandler )
38 , mKeyboardHandler( new
Qt3DInput::QKeyboardHandler )
40 mMouseHandler->setSourceDevice(
new Qt3DInput::QMouseDevice() );
41 connect( mMouseHandler, &Qt3DInput::QMouseHandler::positionChanged,
42 this, &QgsCameraController::onPositionChanged );
43 connect( mMouseHandler, &Qt3DInput::QMouseHandler::wheel,
44 this, &QgsCameraController::onWheel );
45 connect( mMouseHandler, &Qt3DInput::QMouseHandler::pressed,
46 this, &QgsCameraController::onMousePressed );
47 connect( mMouseHandler, &Qt3DInput::QMouseHandler::released,
48 this, &QgsCameraController::onMouseReleased );
49 addComponent( mMouseHandler );
51 mKeyboardHandler->setSourceDevice(
new Qt3DInput::QKeyboardDevice() );
52 connect( mKeyboardHandler, &Qt3DInput::QKeyboardHandler::pressed,
53 this, &QgsCameraController::onKeyPressed );
54 connect( mKeyboardHandler, &Qt3DInput::QKeyboardHandler::released,
55 this, &QgsCameraController::onKeyReleased );
56 addComponent( mKeyboardHandler );
59 connect(
this, &Qt3DCore::QEntity::enabledChanged,
60 mMouseHandler, &Qt3DInput::QMouseHandler::setEnabled );
61 connect(
this, &Qt3DCore::QEntity::enabledChanged,
62 mKeyboardHandler, &Qt3DInput::QKeyboardHandler::setEnabled );
64 mFpsNavTimer =
new QTimer(
this );
65 mFpsNavTimer->setInterval( 10 );
66 connect( mFpsNavTimer, &QTimer::timeout,
this, &QgsCameraController::applyFlyModeKeyMovements );
67 mFpsNavTimer->start();
72QWindow *QgsCameraController::window()
const
75 return windowEngine ? windowEngine->
window() :
nullptr;
80 if ( navigationMode == mCameraNavigationMode )
83 mCameraNavigationMode = navigationMode;
84 mIgnoreNextMouseMove =
true;
90 if ( movementSpeed == mCameraMovementSpeed )
93 mCameraMovementSpeed = movementSpeed;
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;
192 QDomElement elemCamera = doc.createElement( QStringLiteral(
"camera" ) );
193 elemCamera.setAttribute( QStringLiteral(
"x" ), mCameraPose.
centerPoint().
x() );
194 elemCamera.setAttribute( QStringLiteral(
"y" ), mCameraPose.
centerPoint().
z() );
195 elemCamera.setAttribute( QStringLiteral(
"elev" ), mCameraPose.
centerPoint().
y() );
197 elemCamera.setAttribute( QStringLiteral(
"pitch" ), mCameraPose.
pitchAngle() );
198 elemCamera.setAttribute( QStringLiteral(
"yaw" ), mCameraPose.
headingAngle() );
204 const float x = elem.attribute( QStringLiteral(
"x" ) ).toFloat();
205 const float y = elem.attribute( QStringLiteral(
"y" ) ).toFloat();
206 const float elev = elem.attribute( QStringLiteral(
"elev" ) ).toFloat();
207 const float dist = elem.attribute( QStringLiteral(
"dist" ) ).toFloat();
208 const float pitch = elem.attribute( QStringLiteral(
"pitch" ) ).toFloat();
209 const float yaw = elem.attribute( QStringLiteral(
"yaw" ) ).toFloat();
213double QgsCameraController::sampleDepthBuffer(
const QImage &buffer,
int px,
int py )
218 for (
int x = px - 3; x <= px + 3; ++x )
220 for (
int y = py - 3; y <= py + 3; ++y )
222 if ( buffer.valid( x, y ) )
234 int samplesCount = 0;
235 for (
int x = 0; x < buffer.width(); ++x )
237 for (
int y = 0; y < buffer.height(); ++y )
249 if ( samplesCount == 0 )
252 depth /= samplesCount;
257void QgsCameraController::updateCameraFromPose()
264void QgsCameraController::moveCameraPositionBy(
const QVector3D &posDiff )
267 updateCameraFromPose();
270void QgsCameraController::onPositionChanged( Qt3DInput::QMouseEvent *mouse )
272 switch ( mCameraNavigationMode )
275 onPositionChangedTerrainNavigation( mouse );
279 onPositionChangedFlyNavigation( mouse );
284bool QgsCameraController::screenPointToWorldPos( QPoint position, Qt3DRender::QCamera *cameraBefore,
double &depth, QVector3D &worldPosition )
286 depth = sampleDepthBuffer( mDepthBufferImage, position.x(), position.y() );
287 if ( !std::isfinite( depth ) )
289 QgsDebugMsgLevel( QStringLiteral(
"screenPointToWorldPos: depth is NaN or Inf. This should not happen." ), 2 );
295 if ( !std::isfinite( worldPosition.x() ) || !std::isfinite( worldPosition.y() ) || !std::isfinite( worldPosition.z() ) )
297 QgsDebugMsgLevel( QStringLiteral(
"screenPointToWorldPos: position is NaN or Inf. This should not happen." ), 2 );
307void QgsCameraController::onPositionChangedTerrainNavigation( Qt3DInput::QMouseEvent *mouse )
309 if ( mIgnoreNextMouseMove )
311 mIgnoreNextMouseMove =
false;
312 mMousePos = QPoint( mouse->x(), mouse->y() );
316 const int dx = mouse->x() - mMousePos.x();
317 const int dy = mouse->y() - mMousePos.y();
319 const bool hasShift = ( mouse->modifiers() & Qt::ShiftModifier );
320 const bool hasCtrl = ( mouse->modifiers() & Qt::ControlModifier );
321 const bool hasLeftButton = ( mouse->buttons() & Qt::LeftButton );
322 const bool hasMiddleButton = ( mouse->buttons() & Qt::MiddleButton );
323 const bool hasRightButton = ( mouse->buttons() & Qt::RightButton );
325 if ( ( hasLeftButton && hasShift && !hasCtrl ) || ( hasMiddleButton && !hasShift && !hasCtrl ) )
330 float pitchDiff = 180 * ( mouse->y() - mMiddleButtonClickPos.y() ) / scale;
331 float yawDiff = -180 * ( mouse->x() - mMiddleButtonClickPos.x() ) / scale;
333 if ( !mDepthBufferIsReady )
336 if ( !mRotationCenterCalculated )
339 QVector3D worldPosition;
340 if ( screenPointToWorldPos( mMiddleButtonClickPos, mCameraBeforeRotation.get(), depth, worldPosition ) )
342 mRotationCenter = worldPosition;
343 mRotationDistanceFromCenter = ( mRotationCenter - mCameraBeforeRotation->position() ).length();
345 mRotationCenterCalculated =
true;
351 QVector3D shiftVector = mRotationCenter - mCamera->viewCenter();
353 QVector3D newViewCenterWorld =
camera()->viewCenter() + shiftVector;
354 QVector3D newCameraPosition =
camera()->position() + shiftVector;
360 updateCameraFromPose();
368 QVector3D clickedPositionWorld = ray.
origin() + mRotationDistanceFromCenter * ray.
direction();
370 QVector3D shiftVector = clickedPositionWorld - mCamera->viewCenter();
372 QVector3D newViewCenterWorld =
camera()->viewCenter() - shiftVector;
373 QVector3D newCameraPosition =
camera()->position() - shiftVector;
377 updateCameraFromPose();
380 else if ( hasLeftButton && hasCtrl && !hasShift )
383 const float diffPitch = 0.2f * dy;
384 const float diffYaw = - 0.2f * dx;
387 else if ( hasLeftButton && !hasShift && !hasCtrl )
391 if ( !mDepthBufferIsReady )
394 if ( !mDragPointCalculated )
397 QVector3D worldPosition;
398 if ( screenPointToWorldPos( mDragButtonClickPos, mCameraBeforeDrag.get(), depth, worldPosition ) )
401 mDragPoint = worldPosition;
402 mDragPointCalculated =
true;
407 QVector3D cameraBeforeDragPos = mCameraBeforeDrag->position();
410 QVector3D cameraBeforeToMoveToPos = ( moveToPosition - mCameraBeforeDrag->position() ).normalized();
411 QVector3D cameraBeforeToDragPointPos = ( mDragPoint - mCameraBeforeDrag->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( mCameraBeforeDrag->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 if ( !mDepthBufferIsReady )
451 if ( !mDragPointCalculated )
454 QVector3D worldPosition;
455 if ( screenPointToWorldPos( mDragButtonClickPos, mCameraBeforeDrag.get(), depth, worldPosition ) )
457 mDragPoint = worldPosition;
458 mDragPointCalculated =
true;
462 float dist = ( mCameraBeforeDrag->position() - mDragPoint ).length();
465 int screenHeight = mScene->
engine()->
size().height();
466 QWindow *win = window();
469 yOffset = win->mapToGlobal( QPoint( 0, 0 ) ).y();
470 screenHeight = win->screen()->size().height();
474 if ( mMousePos.y() > mDragButtonClickPos.y() )
476 double f = ( double )( mMousePos.y() - mDragButtonClickPos.y() ) / (
double )( screenHeight - mDragButtonClickPos.y() - yOffset );
477 f = std::max( 0.0, std::min( 1.0, f ) );
478 f = 1 - ( std::expm1( -2 * f ) ) / ( std::expm1( -2 ) );
483 double f = 1 - ( double )( mMousePos.y() + yOffset ) / (
double )( mDragButtonClickPos.y() + yOffset );
484 f = std::max( 0.0, std::min( 1.0, f ) );
485 f = ( std::expm1( 2 * f ) ) / ( std::expm1( 2 ) );
486 dist = dist + 2 * dist * f;
491 QVector3D shiftVector = mDragPoint - mCamera->viewCenter();
493 QVector3D newViewCenterWorld =
camera()->viewCenter() + shiftVector;
497 updateCameraFromPose();
503 QVector3D clickedPositionWorld = ray.
origin() + dist * ray.
direction();
505 QVector3D shiftVector = clickedPositionWorld - mCamera->viewCenter();
507 QVector3D newViewCenterWorld =
camera()->viewCenter() - shiftVector;
508 QVector3D newCameraPosition =
camera()->position() - shiftVector;
512 updateCameraFromPose();
516 mMousePos = QPoint( mouse->x(), mouse->y() );
523 dist -= dist * factor * 0.01f;
525 updateCameraFromPose();
528void QgsCameraController::handleTerrainNavigationWheelZoom()
530 if ( !mDepthBufferIsReady )
533 if ( !mZoomPointCalculated )
536 QVector3D worldPosition;
537 if ( screenPointToWorldPos( mMousePos, mCameraBeforeZoom.get(), depth, worldPosition ) )
539 mZoomPoint = worldPosition;
540 mZoomPointCalculated =
true;
544 float f = mCumulatedWheelY / ( 120.0 * 24.0 );
546 double dist = ( mZoomPoint - mCameraBeforeZoom->position() ).length();
551 QVector3D shiftVector = mZoomPoint - mCamera->viewCenter();
553 QVector3D newViewCenterWorld =
camera()->viewCenter() + shiftVector;
557 updateCameraFromPose();
563 QVector3D clickedPositionWorld = ray.
origin() + dist * ray.
direction();
565 QVector3D shiftVector = clickedPositionWorld - mCamera->viewCenter();
567 QVector3D newViewCenterWorld =
camera()->viewCenter() - shiftVector;
568 QVector3D newCameraPosition =
camera()->position() - shiftVector;
572 updateCameraFromPose();
574 mIsInZoomInState =
false;
575 mCumulatedWheelY = 0;
578void QgsCameraController::onWheel( Qt3DInput::QWheelEvent *wheel )
580 switch ( mCameraNavigationMode )
584 const float scaling = ( ( wheel->modifiers() & Qt::ControlModifier ) != 0 ? 0.1f : 1.0f ) / 1000.f;
585 setCameraMovementSpeed( mCameraMovementSpeed + mCameraMovementSpeed * scaling * wheel->angleDelta().y() );
592 const float scaling = ( ( wheel->modifiers() & Qt::ControlModifier ) != 0 ? 0.5f : 5.f );
596 mCumulatedWheelY += scaling * wheel->angleDelta().y();
598 if ( !mIsInZoomInState )
602 mCameraBeforeZoom->setProjectionMatrix( mCamera->projectionMatrix() );
603 mCameraBeforeZoom->setNearPlane( mCamera->nearPlane() );
604 mCameraBeforeZoom->setFarPlane( mCamera->farPlane() );
605 mCameraBeforeZoom->setAspectRatio( mCamera->aspectRatio() );
606 mCameraBeforeZoom->setFieldOfView( mCamera->fieldOfView() );
608 mZoomPointCalculated =
false;
609 mIsInZoomInState =
true;
610 mDepthBufferIsReady =
false;
614 handleTerrainNavigationWheelZoom();
621void QgsCameraController::onMousePressed( Qt3DInput::QMouseEvent *mouse )
623 mKeyboardHandler->setFocus(
true );
624 if ( mouse->button() == Qt3DInput::QMouseEvent::LeftButton || mouse->button() == Qt3DInput::QMouseEvent::RightButton )
626 mMousePos = QPoint( mouse->x(), mouse->y() );
627 mDragButtonClickPos = QPoint( mouse->x(), mouse->y() );
628 mPressedButton = mouse->button();
629 mMousePressed =
true;
631 if ( mCaptureFpsMouseMovements )
632 mIgnoreNextMouseMove =
true;
636 mCameraBeforeDrag->setProjectionMatrix( mCamera->projectionMatrix() );
637 mCameraBeforeDrag->setNearPlane( mCamera->nearPlane() );
638 mCameraBeforeDrag->setFarPlane( mCamera->farPlane() );
639 mCameraBeforeDrag->setAspectRatio( mCamera->aspectRatio() );
640 mCameraBeforeDrag->setFieldOfView( mCamera->fieldOfView() );
642 mDepthBufferIsReady =
false;
643 mDragPointCalculated =
false;
648 if ( mouse->button() == Qt3DInput::QMouseEvent::MiddleButton || ( ( mouse->modifiers() & Qt::ShiftModifier ) != 0 && mouse->button() == Qt3DInput::QMouseEvent::LeftButton ) )
650 mMousePos = QPoint( mouse->x(), mouse->y() );
651 mMiddleButtonClickPos = QPoint( mouse->x(), mouse->y() );
652 mPressedButton = mouse->button();
653 mMousePressed =
true;
654 if ( mCaptureFpsMouseMovements )
655 mIgnoreNextMouseMove =
true;
656 mDepthBufferIsReady =
false;
657 mRotationCenterCalculated =
false;
662 mCameraPose.
updateCamera( mCameraBeforeRotation.get() );
664 mCameraBeforeRotation->setProjectionMatrix( mCamera->projectionMatrix() );
665 mCameraBeforeRotation->setNearPlane( mCamera->nearPlane() );
666 mCameraBeforeRotation->setFarPlane( mCamera->farPlane() );
667 mCameraBeforeRotation->setAspectRatio( mCamera->aspectRatio() );
668 mCameraBeforeRotation->setFieldOfView( mCamera->fieldOfView() );
674void QgsCameraController::onMouseReleased( Qt3DInput::QMouseEvent *mouse )
677 mPressedButton = Qt3DInput::QMouseEvent::NoButton;
678 mMousePressed =
false;
680 mDragPointCalculated =
false;
681 mRotationCenterCalculated =
false;
684void QgsCameraController::onKeyPressed( Qt3DInput::QKeyEvent *event )
686 if ( event->modifiers() & Qt::ControlModifier && event->key() == Qt::Key_QuoteLeft )
689 switch ( mCameraNavigationMode )
701 switch ( mCameraNavigationMode )
705 onKeyPressedFlyNavigation( event );
711 onKeyPressedTerrainNavigation( event );
717void QgsCameraController::onKeyPressedTerrainNavigation( Qt3DInput::QKeyEvent *event )
719 const bool hasShift = (
event->modifiers() & Qt::ShiftModifier );
720 const bool hasCtrl = (
event->modifiers() & Qt::ControlModifier );
722 int tx = 0, ty = 0, tElev = 0;
723 switch ( event->key() )
739 case Qt::Key_PageDown:
749 if ( !hasShift && !hasCtrl )
753 else if ( hasShift && !hasCtrl )
759 else if ( hasCtrl && !hasShift )
762 const float diffPitch = ty;
763 const float diffYaw = -tx;
771 center.
set( center.
x(), center.
y() + tElev * 10, center.
z() );
773 updateCameraFromPose();
777void QgsCameraController::onKeyPressedFlyNavigation( Qt3DInput::QKeyEvent *event )
779 switch ( event->key() )
781 case Qt::Key_QuoteLeft:
784 mCaptureFpsMouseMovements = !mCaptureFpsMouseMovements;
785 mIgnoreNextMouseMove =
true;
786 if ( mCaptureFpsMouseMovements )
788 qApp->setOverrideCursor( QCursor( Qt::BlankCursor ) );
792 qApp->restoreOverrideCursor();
800 if ( mCaptureFpsMouseMovements )
802 mCaptureFpsMouseMovements =
false;
803 mIgnoreNextMouseMove =
true;
804 qApp->restoreOverrideCursor();
814 if ( event->isAutoRepeat() )
817 mDepressedKeys.insert( event->key() );
822 const QVector3D cameraUp = mCamera->upVector().normalized();
824 const QVector3D cameraLeft = QVector3D::crossProduct( cameraUp, cameraFront );
826 QVector3D cameraPosDiff( 0.0f, 0.0f, 0.0f );
830 cameraPosDiff += tx * cameraFront;
834 cameraPosDiff += ty * cameraLeft;
838 cameraPosDiff += tz * QVector3D( 0.0f, 1.0f, 0.0f );
841 moveCameraPositionBy( cameraPosDiff );
844void QgsCameraController::applyFlyModeKeyMovements()
847 const bool shiftPressed = mDepressedKeys.contains( Qt::Key_Shift );
848 const bool ctrlPressed = mDepressedKeys.contains( Qt::Key_Control );
850 const double movementSpeed = mCameraMovementSpeed * ( shiftPressed ? 2 : 1 ) * ( ctrlPressed ? 0.1 : 1 );
852 bool changed =
false;
856 if ( mDepressedKeys.contains( Qt::Key_Left ) || mDepressedKeys.contains( Qt::Key_A ) )
862 if ( mDepressedKeys.contains( Qt::Key_Right ) || mDepressedKeys.contains( Qt::Key_D ) )
868 if ( mDepressedKeys.contains( Qt::Key_Up ) || mDepressedKeys.contains( Qt::Key_W ) )
874 if ( mDepressedKeys.contains( Qt::Key_Down ) || mDepressedKeys.contains( Qt::Key_S ) )
882 static constexpr double ELEVATION_MOVEMENT_SCALE = 0.5;
883 if ( mDepressedKeys.contains( Qt::Key_PageUp ) || mDepressedKeys.contains( Qt::Key_E ) )
886 z += ELEVATION_MOVEMENT_SCALE * movementSpeed;
889 if ( mDepressedKeys.contains( Qt::Key_PageDown ) || mDepressedKeys.contains( Qt::Key_Q ) )
892 z -= ELEVATION_MOVEMENT_SCALE * movementSpeed;
899void QgsCameraController::onPositionChangedFlyNavigation( Qt3DInput::QMouseEvent *mouse )
901 const bool hasMiddleButton = ( mouse->buttons() & Qt::MiddleButton );
902 const bool hasRightButton = ( mouse->buttons() & Qt::RightButton );
904 const double dx = mCaptureFpsMouseMovements ? QCursor::pos().x() - mMousePos.x() : mouse->x() - mMousePos.x();
905 const double dy = mCaptureFpsMouseMovements ? QCursor::pos().y() - mMousePos.y() : mouse->y() - mMousePos.y();
906 mMousePos = mCaptureFpsMouseMovements ? QCursor::pos() : QPoint( mouse->x(), mouse->y() );
908 if ( mIgnoreNextMouseMove )
910 mIgnoreNextMouseMove =
false;
914 if ( hasMiddleButton )
917 const QVector3D cameraUp = mCamera->upVector().normalized();
919 const QVector3D cameraLeft = QVector3D::crossProduct( cameraUp, cameraFront );
920 const QVector3D cameraPosDiff = -dx * cameraLeft - dy * cameraUp;
921 moveCameraPositionBy( mCameraMovementSpeed * cameraPosDiff / 10.0 );
923 else if ( hasRightButton )
927 const QVector3D cameraPosDiff = dy * cameraFront;
928 moveCameraPositionBy( mCameraMovementSpeed * cameraPosDiff / 5.0 );
932 if ( mCaptureFpsMouseMovements )
934 float diffPitch = -0.2f * dy;
935 switch ( mVerticalAxisInversion )
946 const float diffYaw = - 0.2f * dx;
949 else if ( mouse->buttons() & Qt::LeftButton )
951 float diffPitch = -0.2f * dy;
952 switch ( mVerticalAxisInversion )
962 const float diffYaw = - 0.2f * dx;
967 if ( mCaptureFpsMouseMovements )
969 mIgnoreNextMouseMove =
true;
976void QgsCameraController::onKeyReleased( Qt3DInput::QKeyEvent *event )
978 if ( event->isAutoRepeat() )
981 mDepressedKeys.remove( event->key() );
990 updateCameraFromPose();
999 updateCameraFromPose();
1005 updateCameraFromPose();
1012 const float x = tx * dist * 0.02f;
1013 const float y = -ty * dist * 0.02f;
1016 const float t = sqrt( x * x + y * y );
1017 const float a = atan2( y, x ) -
yaw * M_PI / 180;
1018 const float dx = cos( a ) * t;
1019 const float dy = sin( a ) * t;
1022 center.
set( center.
x() + dx, center.
y(), center.
z() + dy );
1024 updateCameraFromPose();
1029 if ( event->key() == Qt::Key_QuoteLeft )
1032 switch ( mCameraNavigationMode )
1036 switch ( event->key() )
1046 case Qt::Key_PageUp:
1048 case Qt::Key_PageDown:
1052 case Qt::Key_Escape:
1053 if ( mCaptureFpsMouseMovements )
1065 switch ( event->key() )
1069 case Qt::Key_PageUp:
1070 case Qt::Key_PageDown:
1084 mDepthBufferImage = depthImage;
1085 mDepthBufferIsReady =
true;
1087 if ( mIsInZoomInState )
1088 handleTerrainNavigationWheelZoom();
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()
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()
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.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
#define QgsDebugMsgLevel(str, level)