QGIS API Documentation  3.24.2-Tisler (13c1a02865)
qgscameracontroller.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgscameracontroller.h
3  --------------------------------------
4  Date : July 2017
5  Copyright : (C) 2017 by Martin Dobias
6  Email : wonder dot sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #ifndef QGSCAMERACONTROLLER_H
17 #define QGSCAMERACONTROLLER_H
18 
19 #include "qgis_3d.h"
20 
21 #include <QPointer>
22 #include <QRect>
23 #include <Qt3DCore/QEntity>
24 #include <Qt3DInput/QMouseEvent>
25 #include <QImage>
26 
27 namespace Qt3DInput
28 {
29  class QKeyEvent;
30  class QKeyboardDevice;
31  class QKeyboardHandler;
32  class QMouseEvent;
33  class QMouseDevice;
34  class QMouseHandler;
35  class QWheelEvent;
36 }
37 
38 namespace Qt3DRender
39 {
40  class QCamera;
41  class QPickEvent;
42 }
43 
44 #include "qgscamerapose.h"
45 
46 class QDomDocument;
47 class QDomElement;
48 
49 class QgsCameraPose;
50 class QgsTerrainEntity;
51 class QgsVector3D;
52 
53 #define SIP_NO_FILE
54 
61 class _3D_EXPORT QgsCameraController : public Qt3DCore::QEntity
62 {
63  Q_OBJECT
64  Q_PROPERTY( Qt3DRender::QCamera *camera READ camera WRITE setCamera NOTIFY cameraChanged )
65  Q_PROPERTY( QRect viewport READ viewport WRITE setViewport NOTIFY viewportChanged )
66  public:
67 
70  {
72  WalkNavigation
73  };
74  Q_ENUM( NavigationMode )
75 
76 
78  {
82  };
83  Q_ENUM( VerticalAxisInversion )
84 
85  public:
87  QgsCameraController( Qt3DCore::QNode *parent = nullptr );
88 
90  Qt3DRender::QCamera *camera() const { return mCamera; }
92  QRect viewport() const { return mViewport; }
93 
98  QgsCameraController::NavigationMode cameraNavigationMode() const { return mCameraNavigationMode; }
99 
104  double cameraMovementSpeed() const { return mCameraMovementSpeed; }
105 
110  void setCameraMovementSpeed( double movementSpeed );
111 
116  QgsCameraController::VerticalAxisInversion verticalAxisInversion() const { return mVerticalAxisInversion; }
117 
122  void setVerticalAxisInversion( QgsCameraController::VerticalAxisInversion inversion );
123 
129  void setTerrainEntity( QgsTerrainEntity *te );
130 
132  void setCamera( Qt3DRender::QCamera *camera );
134  void setViewport( QRect viewport );
136  void frameTriggered( float dt );
137 
139  void resetView( float distance );
140 
142  void setViewFromTop( float worldX, float worldY, float distance, float yaw = 0 );
143 
145  QgsVector3D lookingAtPoint() const;
146 
153  void setLookingAtPoint( const QgsVector3D &point, float distance, float pitch, float yaw );
154 
159  void setCameraPose( const QgsCameraPose &camPose );
160 
165  QgsCameraPose cameraPose() const { return mCameraPose; }
166 
171  float distance() const { return mCameraPose.distanceFromCenterPoint(); }
172 
178  float pitch() const { return mCameraPose.pitchAngle(); }
179 
185  float yaw() const { return mCameraPose.headingAngle(); }
186 
188  QDomElement writeXml( QDomDocument &doc ) const;
190  void readXml( const QDomElement &elem );
191 
193  void zoom( float factor );
195  void tiltUpAroundViewCenter( float deltaPitch );
197  void rotateAroundViewCenter( float deltaYaw );
199  void setCameraHeadingAngle( float angle );
201  void moveView( float tx, float ty );
202 
208  bool willHandleKeyEvent( QKeyEvent *event );
209 
210  public slots:
211 
216  void setCameraNavigationMode( QgsCameraController::NavigationMode navigationMode );
217 
222  void depthBufferCaptured( const QImage &depthImage );
223 
224  private:
225  void rotateCamera( float diffPitch, float diffYaw );
226  void updateCameraFromPose();
227  void moveCameraPositionBy( const QVector3D &posDiff );
228 
229  signals:
236 
240  void cameraMovementSpeedChanged( double speed );
241 
246  void setCursorPosition( QPoint point );
247 
253 
258  void cameraRotationCenterChanged( QVector3D position );
259 
260  private slots:
261  void onPositionChanged( Qt3DInput::QMouseEvent *mouse );
262  void onWheel( Qt3DInput::QWheelEvent *wheel );
263  void onMousePressed( Qt3DInput::QMouseEvent *mouse );
264  void onMouseReleased( Qt3DInput::QMouseEvent *mouse );
265  void onKeyPressed( Qt3DInput::QKeyEvent *event );
266  void onKeyReleased( Qt3DInput::QKeyEvent *event );
267  void onPickerMousePressed( Qt3DRender::QPickEvent *pick );
268  void applyFlyModeKeyMovements();
269 
270  private:
271  void onKeyPressedFlyNavigation( Qt3DInput::QKeyEvent *event );
272  void onKeyPressedTerrainNavigation( Qt3DInput::QKeyEvent *event );
273  void onPositionChangedFlyNavigation( Qt3DInput::QMouseEvent *mouse );
274  void onPositionChangedTerrainNavigation( Qt3DInput::QMouseEvent *mouse );
275 
276  void handleTerrainNavigationWheelZoom();
277 
278  double cameraCenterElevation();
279 
284  double sampleDepthBuffer( const QImage &buffer, int px, int py );
285 
286  private:
288  Qt3DRender::QCamera *mCamera = nullptr;
290  QRect mViewport;
292  float mLastPressedHeight = 0;
293 
294  QPointer<QgsTerrainEntity> mTerrainEntity;
295 
297  QgsCameraPose mCameraPose;
298 
300  QPoint mMousePos;
301  bool mMousePressed = false;
302  Qt3DInput::QMouseEvent::Buttons mPressedButton = Qt3DInput::QMouseEvent::Buttons::NoButton;
303 
304  bool mDepthBufferIsReady = false;
305  QImage mDepthBufferImage;
306 
307  QPoint mMiddleButtonClickPos;
308  bool mRotationCenterCalculated = false;
309  QVector3D mRotationCenter;
310  double mRotationDistanceFromCenter;
311  double mRotationPitch = 0;
312  double mRotationYaw = 0;
313  std::unique_ptr< Qt3DRender::QCamera > mCameraBeforeRotation;
314 
315  QPoint mDragButtonClickPos;
316  std::unique_ptr< Qt3DRender::QCamera > mCameraBeforeDrag;
317  bool mDragPointCalculated = false;
318  QVector3D mDragPoint;
319  double mDragDepth;
320 
321  bool mIsInZoomInState = false;
322  std::unique_ptr< Qt3DRender::QCamera > mCameraBeforeZoom;
323  bool mZoomPointCalculated = false;
324  QVector3D mZoomPoint;
325 
327  Qt3DInput::QMouseDevice *mMouseDevice = nullptr;
328  Qt3DInput::QKeyboardDevice *mKeyboardDevice = nullptr;
329 
330  Qt3DInput::QMouseHandler *mMouseHandler = nullptr;
331  Qt3DInput::QKeyboardHandler *mKeyboardHandler = nullptr;
332  NavigationMode mCameraNavigationMode = NavigationMode::TerrainBasedNavigation;
333  VerticalAxisInversion mVerticalAxisInversion = WhenDragging;
334  double mCameraMovementSpeed = 5.0;
335 
336  QSet< int > mDepressedKeys;
337  bool mCaptureFpsMouseMovements = false;
338  bool mIgnoreNextMouseMove = false;
339  QTimer *mFpsNavTimer = nullptr;
340 
341  double mCumulatedWheelY = 0;
342 
343 };
344 
345 #endif // QGSCAMERACONTROLLER_H
QgsCameraController::NavigationMode cameraNavigationMode() const
Returns the navigation mode used by the camera controller.
QgsCameraPose cameraPose() const
Returns camera pose.
QRect viewport() const
Returns viewport rectangle.
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.
float yaw() const
Returns yaw angle in degrees.
void requestDepthBufferCapture()
Emitted to ask for the depth buffer image.
void navigationModeHotKeyPressed(QgsCameraController::NavigationMode mode)
Emitted when the navigation mode is changed using the hotkey ctrl + ~.
float distance() const
Returns distance of the camera from the point it is looking at.
VerticalAxisInversion
Vertical axis inversion options.
@ WhenDragging
Invert vertical axis movements when dragging in first person modes.
@ Always
Always invert vertical axis movements.
@ Never
Never invert vertical axis movements.
double cameraMovementSpeed() const
Returns the camera movement speed.
void cameraChanged()
Emitted when camera has been updated.
void cameraMovementSpeedChanged(double speed)
Emitted whenever the camera movement speed is changed by the controller.
QgsCameraController::VerticalAxisInversion verticalAxisInversion() const
Returns the vertical axis inversion behavior.
NavigationMode
The navigation mode used by the camera.
@ TerrainBasedNavigation
The default navigation based on the terrain.
void cameraRotationCenterChanged(QVector3D position)
Emitted when the camera rotation center changes.
void viewportChanged()
Emitted when viewport rectangle has been updated.
void setCursorPosition(QPoint point)
Emitted when the mouse cursor position should be moved to the specified point on the map viewport.
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)
Definition: MathUtils.cpp:786