QGIS API Documentation  3.27.0-Master (0e23467727)
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 
172  float distance() const { return mCameraPose.distanceFromCenterPoint(); }
173 
179  float pitch() const { return mCameraPose.pitchAngle(); }
180 
186  float yaw() const { return mCameraPose.headingAngle(); }
187 
189  QDomElement writeXml( QDomDocument &doc ) const;
191  void readXml( const QDomElement &elem );
192 
194  void zoom( float factor );
196  void tiltUpAroundViewCenter( float deltaPitch );
198  void rotateAroundViewCenter( float deltaYaw );
200  void setCameraHeadingAngle( float angle );
202  void moveView( float tx, float ty );
203 
209  bool willHandleKeyEvent( QKeyEvent *event );
210 
211  public slots:
212 
217  void setCameraNavigationMode( QgsCameraController::NavigationMode navigationMode );
218 
223  void depthBufferCaptured( const QImage &depthImage );
224 
225  private:
226  void rotateCamera( float diffPitch, float diffYaw );
227  void updateCameraFromPose();
228  void moveCameraPositionBy( const QVector3D &posDiff );
229 
230  signals:
237 
241  void cameraMovementSpeedChanged( double speed );
242 
247  void setCursorPosition( QPoint point );
248 
254 
259  void cameraRotationCenterChanged( QVector3D position );
260 
261  private slots:
262  void onPositionChanged( Qt3DInput::QMouseEvent *mouse );
263  void onWheel( Qt3DInput::QWheelEvent *wheel );
264  void onMousePressed( Qt3DInput::QMouseEvent *mouse );
265  void onMouseReleased( Qt3DInput::QMouseEvent *mouse );
266  void onKeyPressed( Qt3DInput::QKeyEvent *event );
267  void onKeyReleased( Qt3DInput::QKeyEvent *event );
268  void onPickerMousePressed( Qt3DRender::QPickEvent *pick );
269  void applyFlyModeKeyMovements();
270 
271  private:
272  void onKeyPressedFlyNavigation( Qt3DInput::QKeyEvent *event );
273  void onKeyPressedTerrainNavigation( Qt3DInput::QKeyEvent *event );
274  void onPositionChangedFlyNavigation( Qt3DInput::QMouseEvent *mouse );
275  void onPositionChangedTerrainNavigation( Qt3DInput::QMouseEvent *mouse );
276 
277  void handleTerrainNavigationWheelZoom();
278 
283  double sampleDepthBuffer( const QImage &buffer, int px, int py );
284 
285  private:
287  Qt3DRender::QCamera *mCamera = nullptr;
289  QRect mViewport;
291  float mLastPressedHeight = 0;
292 
293  QPointer<QgsTerrainEntity> mTerrainEntity;
294 
296  QgsCameraPose mCameraPose;
297 
299  QPoint mMousePos;
300  bool mMousePressed = false;
301  Qt3DInput::QMouseEvent::Buttons mPressedButton = Qt3DInput::QMouseEvent::Buttons::NoButton;
302 
303  bool mDepthBufferIsReady = false;
304  QImage mDepthBufferImage;
305 
306  QPoint mMiddleButtonClickPos;
307  bool mRotationCenterCalculated = false;
308  QVector3D mRotationCenter;
309  double mRotationDistanceFromCenter;
310  double mRotationPitch = 0;
311  double mRotationYaw = 0;
312  std::unique_ptr< Qt3DRender::QCamera > mCameraBeforeRotation;
313 
314  QPoint mDragButtonClickPos;
315  std::unique_ptr< Qt3DRender::QCamera > mCameraBeforeDrag;
316  bool mDragPointCalculated = false;
317  QVector3D mDragPoint;
318  double mDragDepth;
319 
320  bool mIsInZoomInState = false;
321  std::unique_ptr< Qt3DRender::QCamera > mCameraBeforeZoom;
322  bool mZoomPointCalculated = false;
323  QVector3D mZoomPoint;
324 
326  Qt3DInput::QMouseDevice *mMouseDevice = nullptr;
327  Qt3DInput::QKeyboardDevice *mKeyboardDevice = nullptr;
328 
329  Qt3DInput::QMouseHandler *mMouseHandler = nullptr;
330  Qt3DInput::QKeyboardHandler *mKeyboardHandler = nullptr;
331  NavigationMode mCameraNavigationMode = NavigationMode::TerrainBasedNavigation;
332  VerticalAxisInversion mVerticalAxisInversion = WhenDragging;
333  double mCameraMovementSpeed = 5.0;
334 
335  QSet< int > mDepressedKeys;
336  bool mCaptureFpsMouseMovements = false;
337  bool mIgnoreNextMouseMove = false;
338  QTimer *mFpsNavTimer = nullptr;
339 
340  double mCumulatedWheelY = 0;
341 
342 };
343 
344 #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 navigationModeChanged(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