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 )
95 mCameraMovementSpeed = std::clamp( movementSpeed, 0.05, 150.0 );
101 mVerticalAxisInversion = inversion;
109 if (
pitch + diffPitch > 180 )
110 diffPitch = 180 -
pitch;
111 if (
pitch + diffPitch < 0 )
112 diffPitch = 0 -
pitch;
119 const QQuaternion q = QQuaternion::fromEulerAngles(
pitch + diffPitch,
yaw + diffYaw, 0 ) *
120 QQuaternion::fromEulerAngles(
pitch,
yaw, 0 ).conjugated();
123 const QVector3D position = mCamera->position();
124 QVector3D viewCenter = mCamera->viewCenter();
125 const QVector3D viewVector = viewCenter - position;
126 const QVector3D cameraToCenter = q * viewVector;
127 viewCenter = position + cameraToCenter;
132 updateCameraFromPose();
158 mCamera->setNearPlane(
distance / 2 );
159 mCamera->setFarPlane(
distance * 2 );
181 if ( camPose == mCameraPose )
184 mCameraPose = camPose;
194 QDomElement elemCamera = doc.createElement( QStringLiteral(
"camera" ) );
195 elemCamera.setAttribute( QStringLiteral(
"x" ), mCameraPose.
centerPoint().
x() );
196 elemCamera.setAttribute( QStringLiteral(
"y" ), mCameraPose.
centerPoint().
z() );
197 elemCamera.setAttribute( QStringLiteral(
"elev" ), mCameraPose.
centerPoint().
y() );
199 elemCamera.setAttribute( QStringLiteral(
"pitch" ), mCameraPose.
pitchAngle() );
200 elemCamera.setAttribute( QStringLiteral(
"yaw" ), mCameraPose.
headingAngle() );
206 const float x = elem.attribute( QStringLiteral(
"x" ) ).toFloat();
207 const float y = elem.attribute( QStringLiteral(
"y" ) ).toFloat();
208 const float elev = elem.attribute( QStringLiteral(
"elev" ) ).toFloat();
209 const float dist = elem.attribute( QStringLiteral(
"dist" ) ).toFloat();
210 const float pitch = elem.attribute( QStringLiteral(
"pitch" ) ).toFloat();
211 const float yaw = elem.attribute( QStringLiteral(
"yaw" ) ).toFloat();
215double QgsCameraController::sampleDepthBuffer(
const QImage &buffer,
int px,
int py )
220 for (
int x = px - 3; x <= px + 3; ++x )
222 for (
int y = py - 3; y <= py + 3; ++y )
224 if ( buffer.valid( x, y ) )
236 int samplesCount = 0;
237 for (
int x = 0; x < buffer.width(); ++x )
239 for (
int y = 0; y < buffer.height(); ++y )
251 if ( samplesCount == 0 )
254 depth /= samplesCount;
259void QgsCameraController::updateCameraFromPose()
266void QgsCameraController::moveCameraPositionBy(
const QVector3D &posDiff )
269 updateCameraFromPose();
272void QgsCameraController::onPositionChanged( Qt3DInput::QMouseEvent *mouse )
274 switch ( mCameraNavigationMode )
277 onPositionChangedTerrainNavigation( mouse );
281 onPositionChangedFlyNavigation( mouse );
286bool QgsCameraController::screenPointToWorldPos( QPoint position, Qt3DRender::QCamera *cameraBefore,
double &depth, QVector3D &worldPosition )
288 depth = sampleDepthBuffer( mDepthBufferImage, position.x(), position.y() );
289 if ( !std::isfinite( depth ) )
291 QgsDebugMsgLevel( QStringLiteral(
"screenPointToWorldPos: depth is NaN or Inf. This should not happen." ), 2 );
297 if ( !std::isfinite( worldPosition.x() ) || !std::isfinite( worldPosition.y() ) || !std::isfinite( worldPosition.z() ) )
299 QgsDebugMsgLevel( QStringLiteral(
"screenPointToWorldPos: position is NaN or Inf. This should not happen." ), 2 );
309void QgsCameraController::onPositionChangedTerrainNavigation( Qt3DInput::QMouseEvent *mouse )
311 if ( mIgnoreNextMouseMove )
313 mIgnoreNextMouseMove =
false;
314 mMousePos = QPoint( mouse->x(), mouse->y() );
318 const int dx = mouse->x() - mMousePos.x();
319 const int dy = mouse->y() - mMousePos.y();
321 const bool hasShift = ( mouse->modifiers() & Qt::ShiftModifier );
322 const bool hasCtrl = ( mouse->modifiers() & Qt::ControlModifier );
323 const bool hasLeftButton = ( mouse->buttons() & Qt::LeftButton );
324 const bool hasMiddleButton = ( mouse->buttons() & Qt::MiddleButton );
325 const bool hasRightButton = ( mouse->buttons() & Qt::RightButton );
327 if ( ( hasLeftButton && hasShift && !hasCtrl ) || ( hasMiddleButton && !hasShift && !hasCtrl ) )
332 float pitchDiff = 180 * ( mouse->y() - mMiddleButtonClickPos.y() ) / scale;
333 float yawDiff = -180 * ( mouse->x() - mMiddleButtonClickPos.x() ) / scale;
335 if ( !mDepthBufferIsReady )
338 if ( !mRotationCenterCalculated )
341 QVector3D worldPosition;
342 if ( screenPointToWorldPos( mMiddleButtonClickPos, mCameraBeforeRotation.get(), depth, worldPosition ) )
344 mRotationCenter = worldPosition;
345 mRotationDistanceFromCenter = ( mRotationCenter - mCameraBeforeRotation->position() ).length();
347 mRotationCenterCalculated =
true;
353 QVector3D shiftVector = mRotationCenter - mCamera->viewCenter();
355 QVector3D newViewCenterWorld =
camera()->viewCenter() + shiftVector;
356 QVector3D newCameraPosition =
camera()->position() + shiftVector;
362 updateCameraFromPose();
370 QVector3D clickedPositionWorld = ray.
origin() + mRotationDistanceFromCenter * ray.
direction();
372 QVector3D shiftVector = clickedPositionWorld - mCamera->viewCenter();
374 QVector3D newViewCenterWorld =
camera()->viewCenter() - shiftVector;
375 QVector3D newCameraPosition =
camera()->position() - shiftVector;
379 updateCameraFromPose();
382 else if ( hasLeftButton && hasCtrl && !hasShift )
385 const float diffPitch = 0.2f * dy;
386 const float diffYaw = - 0.2f * dx;
389 else if ( hasLeftButton && !hasShift && !hasCtrl )
393 if ( !mDepthBufferIsReady )
396 if ( !mDragPointCalculated )
399 QVector3D worldPosition;
400 if ( screenPointToWorldPos( mDragButtonClickPos, mCameraBeforeDrag.get(), depth, worldPosition ) )
403 mDragPoint = worldPosition;
404 mDragPointCalculated =
true;
409 QVector3D cameraBeforeDragPos = mCameraBeforeDrag->position();
412 QVector3D cameraBeforeToMoveToPos = ( moveToPosition - mCameraBeforeDrag->position() ).normalized();
413 QVector3D cameraBeforeToDragPointPos = ( mDragPoint - mCameraBeforeDrag->position() ).normalized();
416 if ( cameraBeforeToMoveToPos.y() == 0 )
418 cameraBeforeToMoveToPos.setY( 0.01 );
419 cameraBeforeToMoveToPos = cameraBeforeToMoveToPos.normalized();
422 if ( cameraBeforeToDragPointPos.y() == 0 )
424 cameraBeforeToDragPointPos.setY( 0.01 );
425 cameraBeforeToDragPointPos = cameraBeforeToDragPointPos.normalized();
428 double d1 = ( mDragPoint.y() - cameraBeforeDragPos.y() ) / cameraBeforeToMoveToPos.y();
429 double d2 = ( mDragPoint.y() - cameraBeforeDragPos.y() ) / cameraBeforeToDragPointPos.y();
431 QVector3D from = cameraBeforeDragPos + d1 * cameraBeforeToMoveToPos;
432 QVector3D to = cameraBeforeDragPos + d2 * cameraBeforeToDragPointPos;
434 QVector3D shiftVector = to - from;
436 mCameraPose.
setCenterPoint( mCameraBeforeDrag->viewCenter() + shiftVector );
437 updateCameraFromPose();
439 else if ( hasLeftButton && hasShift && hasCtrl )
443 double tElev = mMousePos.y() - mouse->y();
444 center.
set( center.
x(), center.
y() + tElev * 0.5, center.
z() );
446 updateCameraFromPose();
448 else if ( hasRightButton && !hasShift && !hasCtrl )
450 if ( !mDepthBufferIsReady )
453 if ( !mDragPointCalculated )
456 QVector3D worldPosition;
457 if ( screenPointToWorldPos( mDragButtonClickPos, mCameraBeforeDrag.get(), depth, worldPosition ) )
459 mDragPoint = worldPosition;
460 mDragPointCalculated =
true;
464 float dist = ( mCameraBeforeDrag->position() - mDragPoint ).length();
467 int screenHeight = mScene->
engine()->
size().height();
468 QWindow *win = window();
471 yOffset = win->mapToGlobal( QPoint( 0, 0 ) ).y();
472 screenHeight = win->screen()->size().height();
476 if ( mMousePos.y() > mDragButtonClickPos.y() )
478 double f = ( double )( mMousePos.y() - mDragButtonClickPos.y() ) / (
double )( screenHeight - mDragButtonClickPos.y() - yOffset );
479 f = std::max( 0.0, std::min( 1.0, f ) );
480 f = 1 - ( std::expm1( -2 * f ) ) / ( std::expm1( -2 ) );
485 double f = 1 - ( double )( mMousePos.y() + yOffset ) / (
double )( mDragButtonClickPos.y() + yOffset );
486 f = std::max( 0.0, std::min( 1.0, f ) );
487 f = ( std::expm1( 2 * f ) ) / ( std::expm1( 2 ) );
488 dist = dist + 2 * dist * f;
493 QVector3D shiftVector = mDragPoint - mCamera->viewCenter();
495 QVector3D newViewCenterWorld =
camera()->viewCenter() + shiftVector;
499 updateCameraFromPose();
505 QVector3D clickedPositionWorld = ray.
origin() + dist * ray.
direction();
507 QVector3D shiftVector = clickedPositionWorld - mCamera->viewCenter();
509 QVector3D newViewCenterWorld =
camera()->viewCenter() - shiftVector;
510 QVector3D newCameraPosition =
camera()->position() - shiftVector;
514 updateCameraFromPose();
518 mMousePos = QPoint( mouse->x(), mouse->y() );
525 dist -= dist * factor * 0.01f;
527 updateCameraFromPose();
530void QgsCameraController::handleTerrainNavigationWheelZoom()
532 if ( !mDepthBufferIsReady )
535 if ( !mZoomPointCalculated )
538 QVector3D worldPosition;
539 if ( screenPointToWorldPos( mMousePos, mCameraBeforeZoom.get(), depth, worldPosition ) )
541 mZoomPoint = worldPosition;
542 mZoomPointCalculated =
true;
546 float f = mCumulatedWheelY / ( 120.0 * 24.0 );
548 double dist = ( mZoomPoint - mCameraBeforeZoom->position() ).length();
553 QVector3D shiftVector = mZoomPoint - mCamera->viewCenter();
555 QVector3D newViewCenterWorld =
camera()->viewCenter() + shiftVector;
559 updateCameraFromPose();
565 QVector3D clickedPositionWorld = ray.
origin() + dist * ray.
direction();
567 QVector3D shiftVector = clickedPositionWorld - mCamera->viewCenter();
569 QVector3D newViewCenterWorld =
camera()->viewCenter() - shiftVector;
570 QVector3D newCameraPosition =
camera()->position() - shiftVector;
574 updateCameraFromPose();
576 mIsInZoomInState =
false;
577 mCumulatedWheelY = 0;
580void QgsCameraController::onWheel( Qt3DInput::QWheelEvent *wheel )
582 switch ( mCameraNavigationMode )
586 const float scaling = ( ( wheel->modifiers() & Qt::ControlModifier ) != 0 ? 0.1f : 1.0f ) / 1000.f;
587 setCameraMovementSpeed( mCameraMovementSpeed + mCameraMovementSpeed * scaling * wheel->angleDelta().y() );
594 const float scaling = ( ( wheel->modifiers() & Qt::ControlModifier ) != 0 ? 0.5f : 5.f );
598 mCumulatedWheelY += scaling * wheel->angleDelta().y();
600 if ( !mIsInZoomInState )
604 mCameraBeforeZoom->setProjectionMatrix( mCamera->projectionMatrix() );
605 mCameraBeforeZoom->setNearPlane( mCamera->nearPlane() );
606 mCameraBeforeZoom->setFarPlane( mCamera->farPlane() );
607 mCameraBeforeZoom->setAspectRatio( mCamera->aspectRatio() );
608 mCameraBeforeZoom->setFieldOfView( mCamera->fieldOfView() );
610 mZoomPointCalculated =
false;
611 mIsInZoomInState =
true;
612 mDepthBufferIsReady =
false;
616 handleTerrainNavigationWheelZoom();
623void QgsCameraController::onMousePressed( Qt3DInput::QMouseEvent *mouse )
625 mKeyboardHandler->setFocus(
true );
626 if ( mouse->button() == Qt3DInput::QMouseEvent::LeftButton || mouse->button() == Qt3DInput::QMouseEvent::RightButton )
628 mMousePos = QPoint( mouse->x(), mouse->y() );
629 mDragButtonClickPos = QPoint( mouse->x(), mouse->y() );
630 mPressedButton = mouse->button();
631 mMousePressed =
true;
633 if ( mCaptureFpsMouseMovements )
634 mIgnoreNextMouseMove =
true;
638 mCameraBeforeDrag->setProjectionMatrix( mCamera->projectionMatrix() );
639 mCameraBeforeDrag->setNearPlane( mCamera->nearPlane() );
640 mCameraBeforeDrag->setFarPlane( mCamera->farPlane() );
641 mCameraBeforeDrag->setAspectRatio( mCamera->aspectRatio() );
642 mCameraBeforeDrag->setFieldOfView( mCamera->fieldOfView() );
644 mDepthBufferIsReady =
false;
645 mDragPointCalculated =
false;
650 if ( mouse->button() == Qt3DInput::QMouseEvent::MiddleButton || ( ( mouse->modifiers() & Qt::ShiftModifier ) != 0 && mouse->button() == Qt3DInput::QMouseEvent::LeftButton ) )
652 mMousePos = QPoint( mouse->x(), mouse->y() );
653 mMiddleButtonClickPos = QPoint( mouse->x(), mouse->y() );
654 mPressedButton = mouse->button();
655 mMousePressed =
true;
656 if ( mCaptureFpsMouseMovements )
657 mIgnoreNextMouseMove =
true;
658 mDepthBufferIsReady =
false;
659 mRotationCenterCalculated =
false;
664 mCameraPose.
updateCamera( mCameraBeforeRotation.get() );
666 mCameraBeforeRotation->setProjectionMatrix( mCamera->projectionMatrix() );
667 mCameraBeforeRotation->setNearPlane( mCamera->nearPlane() );
668 mCameraBeforeRotation->setFarPlane( mCamera->farPlane() );
669 mCameraBeforeRotation->setAspectRatio( mCamera->aspectRatio() );
670 mCameraBeforeRotation->setFieldOfView( mCamera->fieldOfView() );
676void QgsCameraController::onMouseReleased( Qt3DInput::QMouseEvent *mouse )
679 mPressedButton = Qt3DInput::QMouseEvent::NoButton;
680 mMousePressed =
false;
682 mDragPointCalculated =
false;
683 mRotationCenterCalculated =
false;
686void QgsCameraController::onKeyPressed( Qt3DInput::QKeyEvent *event )
688 if ( event->modifiers() & Qt::ControlModifier && event->key() == Qt::Key_QuoteLeft )
691 switch ( mCameraNavigationMode )
703 switch ( mCameraNavigationMode )
707 onKeyPressedFlyNavigation( event );
713 onKeyPressedTerrainNavigation( event );
719void QgsCameraController::onKeyPressedTerrainNavigation( Qt3DInput::QKeyEvent *event )
721 const bool hasShift = (
event->modifiers() & Qt::ShiftModifier );
722 const bool hasCtrl = (
event->modifiers() & Qt::ControlModifier );
724 int tx = 0, ty = 0, tElev = 0;
725 switch ( event->key() )
741 case Qt::Key_PageDown:
751 if ( !hasShift && !hasCtrl )
755 else if ( hasShift && !hasCtrl )
761 else if ( hasCtrl && !hasShift )
764 const float diffPitch = ty;
765 const float diffYaw = -tx;
773 center.
set( center.
x(), center.
y() + tElev * 10, center.
z() );
775 updateCameraFromPose();
779void QgsCameraController::onKeyPressedFlyNavigation( Qt3DInput::QKeyEvent *event )
781 switch ( event->key() )
783 case Qt::Key_QuoteLeft:
786 mCaptureFpsMouseMovements = !mCaptureFpsMouseMovements;
787 mIgnoreNextMouseMove =
true;
788 if ( mCaptureFpsMouseMovements )
790 qApp->setOverrideCursor( QCursor( Qt::BlankCursor ) );
794 qApp->restoreOverrideCursor();
802 if ( mCaptureFpsMouseMovements )
804 mCaptureFpsMouseMovements =
false;
805 mIgnoreNextMouseMove =
true;
806 qApp->restoreOverrideCursor();
816 if ( event->isAutoRepeat() )
819 mDepressedKeys.insert( event->key() );
824 const QVector3D cameraUp = mCamera->upVector().normalized();
826 const QVector3D cameraLeft = QVector3D::crossProduct( cameraUp, cameraFront );
828 QVector3D cameraPosDiff( 0.0f, 0.0f, 0.0f );
832 cameraPosDiff += tx * cameraFront;
836 cameraPosDiff += ty * cameraLeft;
840 cameraPosDiff += tz * QVector3D( 0.0f, 1.0f, 0.0f );
843 moveCameraPositionBy( cameraPosDiff );
846void QgsCameraController::applyFlyModeKeyMovements()
849 const bool shiftPressed = mDepressedKeys.contains( Qt::Key_Shift );
850 const bool ctrlPressed = mDepressedKeys.contains( Qt::Key_Control );
852 const double movementSpeed = mCameraMovementSpeed * ( shiftPressed ? 2 : 1 ) * ( ctrlPressed ? 0.1 : 1 );
854 bool changed =
false;
858 if ( mDepressedKeys.contains( Qt::Key_Left ) || mDepressedKeys.contains( Qt::Key_A ) )
864 if ( mDepressedKeys.contains( Qt::Key_Right ) || mDepressedKeys.contains( Qt::Key_D ) )
870 if ( mDepressedKeys.contains( Qt::Key_Up ) || mDepressedKeys.contains( Qt::Key_W ) )
876 if ( mDepressedKeys.contains( Qt::Key_Down ) || mDepressedKeys.contains( Qt::Key_S ) )
884 static constexpr double ELEVATION_MOVEMENT_SCALE = 0.5;
885 if ( mDepressedKeys.contains( Qt::Key_PageUp ) || mDepressedKeys.contains( Qt::Key_E ) )
888 z += ELEVATION_MOVEMENT_SCALE * movementSpeed;
891 if ( mDepressedKeys.contains( Qt::Key_PageDown ) || mDepressedKeys.contains( Qt::Key_Q ) )
894 z -= ELEVATION_MOVEMENT_SCALE * movementSpeed;
901void QgsCameraController::onPositionChangedFlyNavigation( Qt3DInput::QMouseEvent *mouse )
903 const bool hasMiddleButton = ( mouse->buttons() & Qt::MiddleButton );
904 const bool hasRightButton = ( mouse->buttons() & Qt::RightButton );
906 const double dx = mCaptureFpsMouseMovements ? QCursor::pos().x() - mMousePos.x() : mouse->x() - mMousePos.x();
907 const double dy = mCaptureFpsMouseMovements ? QCursor::pos().y() - mMousePos.y() : mouse->y() - mMousePos.y();
908 mMousePos = mCaptureFpsMouseMovements ? QCursor::pos() : QPoint( mouse->x(), mouse->y() );
910 if ( mIgnoreNextMouseMove )
912 mIgnoreNextMouseMove =
false;
916 if ( hasMiddleButton )
919 const QVector3D cameraUp = mCamera->upVector().normalized();
921 const QVector3D cameraLeft = QVector3D::crossProduct( cameraUp, cameraFront );
922 const QVector3D cameraPosDiff = -dx * cameraLeft - dy * cameraUp;
923 moveCameraPositionBy( mCameraMovementSpeed * cameraPosDiff / 10.0 );
925 else if ( hasRightButton )
929 const QVector3D cameraPosDiff = dy * cameraFront;
930 moveCameraPositionBy( mCameraMovementSpeed * cameraPosDiff / 5.0 );
934 if ( mCaptureFpsMouseMovements )
936 float diffPitch = -0.2f * dy;
937 switch ( mVerticalAxisInversion )
948 const float diffYaw = - 0.2f * dx;
951 else if ( mouse->buttons() & Qt::LeftButton )
953 float diffPitch = -0.2f * dy;
954 switch ( mVerticalAxisInversion )
964 const float diffYaw = - 0.2f * dx;
969 if ( mCaptureFpsMouseMovements )
971 mIgnoreNextMouseMove =
true;
978void QgsCameraController::onKeyReleased( Qt3DInput::QKeyEvent *event )
980 if ( event->isAutoRepeat() )
983 mDepressedKeys.remove( event->key() );
992 updateCameraFromPose();
1001 updateCameraFromPose();
1007 updateCameraFromPose();
1014 const float x = tx * dist * 0.02f;
1015 const float y = -ty * dist * 0.02f;
1018 const float t = sqrt( x * x + y * y );
1019 const float a = atan2( y, x ) -
yaw * M_PI / 180;
1020 const float dx = cos( a ) * t;
1021 const float dy = sin( a ) * t;
1024 center.
set( center.
x() + dx, center.
y(), center.
z() + dy );
1026 updateCameraFromPose();
1031 if ( event->key() == Qt::Key_QuoteLeft )
1034 switch ( mCameraNavigationMode )
1038 switch ( event->key() )
1048 case Qt::Key_PageUp:
1050 case Qt::Key_PageDown:
1054 case Qt::Key_Escape:
1055 if ( mCaptureFpsMouseMovements )
1067 switch ( event->key() )
1071 case Qt::Key_PageUp:
1072 case Qt::Key_PageDown:
1086 mDepthBufferImage = depthImage;
1087 mDepthBufferIsReady =
true;
1089 if ( mIsInZoomInState )
1090 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()
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)