QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
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#include "qgscamerapose.h"
22
23#include <QImage>
24#include <Qt3DCore/QEntity>
25#include <Qt3DInput/QMouseEvent>
26
27#ifndef SIP_RUN
28namespace Qt3DInput
29{
30 class QKeyEvent;
31 class QKeyboardHandler;
32 class QMouseEvent;
33 class QMouseHandler;
34 class QWheelEvent;
35} // namespace Qt3DInput
36
37namespace Qt3DRender
38{
39 class QCamera;
40}
41
42#endif
43
44class QDomDocument;
45class QDomElement;
46
47class QgsCameraPose;
48class QgsVector3D;
50class Qgs3DMapScene;
51
56#ifndef SIP_RUN
57class _3D_EXPORT QgsCameraController : public Qt3DCore::QEntity
58{
59#else
60class _3D_EXPORT QgsCameraController : public QObject
61{
62#endif
63
64 Q_OBJECT
65 public:
69
70#ifndef SIP_RUN
71
76 Qt3DRender::QCamera *camera() const { return mCamera; }
77#endif
78
83 Qgis::NavigationMode cameraNavigationMode() const { return mCameraNavigationMode; }
84
89 double cameraMovementSpeed() const { return mCameraMovementSpeed; }
90
95 void setCameraMovementSpeed( double movementSpeed );
96
101 Qgis::VerticalAxisInversion verticalAxisInversion() const { return mVerticalAxisInversion; }
102
107 void setVerticalAxisInversion( Qgis::VerticalAxisInversion inversion );
108
110 void frameTriggered( float dt );
111
113 void resetView( float distance );
114
116 void setViewFromTop( float worldX, float worldY, float distance, float yaw = 0 );
117
119 QgsVector3D lookingAtPoint() const;
120
127 void setLookingAtPoint( const QgsVector3D &point, float distance, float pitch, float yaw );
128
133 QgsVector3D lookingAtMapPoint() const;
134
139 void setLookingAtMapPoint( const QgsVector3D &point, float distance, float pitch, float yaw );
140
145 void setCameraPose( const QgsCameraPose &camPose, bool force = false );
146
151 QgsCameraPose cameraPose() const { return mCameraPose; }
152
158 float distance() const { return mCameraPose.distanceFromCenterPoint(); }
159
165 float pitch() const { return mCameraPose.pitchAngle(); }
166
172 float yaw() const { return mCameraPose.headingAngle(); }
173
175 QDomElement writeXml( QDomDocument &doc ) const;
177 void readXml( const QDomElement &elem, QgsVector3D savedOrigin );
178
180 void zoom( float factor );
182 void tiltUpAroundViewCenter( float deltaPitch );
184 void rotateAroundViewCenter( float deltaYaw );
186 void setCameraHeadingAngle( float angle );
188 void moveView( float tx, float ty );
189
194 void walkView( double tx, double ty, double tz );
195
202 void rotateCamera( float diffPitch, float diffYaw );
203
209 void rotateCameraAroundPivot( float newPitch, float newHeading, const QVector3D &pivotPoint );
210
218 Q_DECL_DEPRECATED void zoomCameraAroundPivot( const QVector3D &oldCameraPosition, double zoomFactor, const QVector3D &pivotPoint ) SIP_DEPRECATED;
219
226 void zoomCameraAroundPivot( const QVector3D &oldCameraPosition, double oldDistanceFromCenterPoint, double zoomFactor, const QVector3D &pivotPoint );
227
232 bool keyboardEventFilter( QKeyEvent *event );
233
240 void setOrigin( const QgsVector3D &origin );
241
246 void setInputHandlersEnabled( bool enable ) { mInputHandlersEnabled = enable; }
247
252 bool hasInputHandlersEnabled() const { return mInputHandlersEnabled; }
253
260 void globeMoveCenterPoint( double latDiff, double lonDiff );
261
267 void globeZoom( float factor );
268
273 void globeUpdatePitchAngle( float angleDiff );
274
279 void globeUpdateHeadingAngle( float angleDiff );
280
286 void resetGlobe( float distance, double lat = 0, double lon = 0 );
287
292 const QgsVector3D origin() const { return mOrigin; }
293
294 // Convenience methods to set camera view to standard positions
296 void rotateCameraToHome() { rotateToRespectingTerrain( 45.0f, 45.0f ); }
298 void rotateCameraToTop() { rotateToRespectingTerrain( 0.0f, 0.0f ); }
300 void rotateCameraToNorth() { rotateToRespectingTerrain( 90.0f, 180.0f ); }
302 void rotateCameraToEast() { rotateToRespectingTerrain( 90.0f, 90.0f ); }
304 void rotateCameraToSouth() { rotateToRespectingTerrain( 90.0f, 0.0f ); }
306 void rotateCameraToWest() { rotateToRespectingTerrain( 90.0f, -90.0f ); }
308 void rotateCameraToBottom() { rotateToRespectingTerrain( 180.0f, 0.0f ); }
309
310 public slots:
311
316 void setCameraNavigationMode( Qgis::NavigationMode navigationMode );
317
322 void depthBufferCaptured( const QImage &depthImage );
323
324 private:
325#ifdef SIP_RUN
328#endif
329
330 void updateCameraFromPose();
331 void moveCameraPositionBy( const QVector3D &posDiff );
333 QWindow *window() const;
334
336 enum class MouseOperation
337 {
338 None = 0, // no operation
339 Translation, // left button pressed, no modifier
340 RotationCamera, // left button pressed + ctrl modifier
341 RotationCenter, // left button pressed + shift modifier
342 Zoom, // right button pressed
343 ZoomWheel // mouse wheel scroll
344 };
345
346 // This list gathers all the rotation and translation operations.
347 // It is used to update the appropriate parameters when successive
348 // translation and rotation happen.
349 const QList<MouseOperation> mTranslateOrRotate = {
350 MouseOperation::Translation,
351 MouseOperation::RotationCamera,
352 MouseOperation::RotationCenter
353 };
354
355 // check that current sequence (current operation and new operation) is a rotation or translation
356 bool isATranslationRotationSequence( MouseOperation newOperation ) const;
357
358 void setMouseParameters( const MouseOperation &newOperation, const QPoint &clickPoint = QPoint() );
359
365 void rotateToRespectingTerrain( float pitch, float yaw );
366
367 signals:
370
373
377 void cameraMovementSpeedChanged( double speed );
378
383 void setCursorPosition( QPoint point );
384
390
395 void cameraRotationCenterChanged( QVector3D position );
396
397 private slots:
398 void onPositionChanged( Qt3DInput::QMouseEvent *mouse );
399 void onWheel( Qt3DInput::QWheelEvent *wheel );
400 void onMousePressed( Qt3DInput::QMouseEvent *mouse );
401 void onMouseReleased( Qt3DInput::QMouseEvent *mouse );
402 void applyFlyModeKeyMovements();
403
404 private:
405 // All three methods return true if event is handled
406 bool onKeyPressedFlyNavigation( QKeyEvent *event );
407 bool onKeyPressedTerrainNavigation( QKeyEvent *event );
408 bool onKeyPressedGlobeTerrainNavigation( QKeyEvent *event );
409 void onPositionChangedFlyNavigation( Qt3DInput::QMouseEvent *mouse );
410 void onPositionChangedTerrainNavigation( Qt3DInput::QMouseEvent *mouse );
411 void onPositionChangedGlobeTerrainNavigation( Qt3DInput::QMouseEvent *mouse );
412
413 void handleTerrainNavigationWheelZoom();
414
421 double sampleDepthBuffer( int px, int py );
422
423 // Returns the average depth of all non void pixels
424 double depthBufferNonVoidAverage();
425
426#ifndef SIP_RUN
428 bool screenPointToWorldPos( QPoint position, double &depth, QVector3D &worldPosition );
429#endif
430
431 // Moves given point (in ECEF) by specified lat/lon angle difference (in degrees) and returns new ECEF point
432 QgsVector3D moveGeocentricPoint( const QgsVector3D &point, double latDiff, double lonDiff );
433
435 Qgs3DMapScene *mScene = nullptr;
436
438 Qt3DRender::QCamera *mCamera = nullptr;
439
441 QgsCameraPose mCameraPose;
442
444 QPoint mMousePos;
445
447 QPoint mClickPoint;
448
449 // false when no depth buffer captured or new capture requested and not yet done.
450 bool mDepthBufferIsReady = false;
451 QImage mDepthBufferImage;
452 // -1 when unset
453 // TODO: Change to std::optional<double>
454 double mDepthBufferNonVoidAverage = -1;
455 // nullptr when !mDepthBufferIsReady
456 std::unique_ptr<Qt3DRender::QCamera> mDepthBufferCamera;
457
458 std::unique_ptr<Qt3DRender::QCamera> mCameraBefore;
459
460 bool mRotationCenterCalculated = false;
461 QVector3D mRotationCenter;
462 double mRotationDistanceFromCenter = 0;
463 float mRotationPitch = 0;
464 float mRotationYaw = 0;
465
466 bool mDragPointCalculated = false;
467 QVector3D mDragPoint;
468 double mDragDepth = 0;
469
470 bool mZoomPointCalculated = false;
471 QVector3D mZoomPoint;
472
473 // used for globe
474 QgsVector3D mMousePressViewCenter;
475 QgsCoordinateTransform mGlobeCrsToLatLon;
476
477 Qt3DInput::QMouseHandler *mMouseHandler = nullptr;
478 Qt3DInput::QKeyboardHandler *mKeyboardHandler = nullptr;
479 bool mInputHandlersEnabled = true;
482 double mCameraMovementSpeed = 5.0;
483
484 QSet<int> mDepressedKeys;
485 bool mCaptureFpsMouseMovements = false;
486 bool mIgnoreNextMouseMove = false;
487 QTimer *mFpsNavTimer = nullptr;
488
489 double mCumulatedWheelY = 0;
490
491 MouseOperation mCurrentOperation = MouseOperation::None;
492
493 // 3D world's origin in map coordinates
494 QgsVector3D mOrigin;
495
497 bool mCameraChanged = false;
498
499 // To test the cameracontroller
500 friend class TestQgs3DRendering;
502};
503
504#endif // QGSCAMERACONTROLLER_H
VerticalAxisInversion
Vertical axis inversion options for 3D views.
Definition qgis.h:4180
@ WhenDragging
Invert vertical axis movements when dragging in first person modes.
Definition qgis.h:4182
NavigationMode
The navigation mode used by 3D cameras.
Definition qgis.h:4155
@ TerrainBased
The default navigation based on the terrain.
Definition qgis.h:4156
Entity that encapsulates our 3D scene - contains all other entities (such as terrain) as children.
Object that controls camera movement based on user input.
void navigationModeChanged(Qgis::NavigationMode mode)
Emitted when the navigation mode is changed using the hotkey ctrl + ~.
bool hasInputHandlersEnabled() const
Returns whether the camera controller responds to mouse and keyboard events.
QgsCameraPose cameraPose() const
Returns camera pose.
void rotateCameraToBottom()
Rotate to bottom-up view.
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.
Qgis::VerticalAxisInversion verticalAxisInversion() const
Returns the vertical axis inversion behavior.
void rotateCameraToTop()
Rotate to top-down view.
void rotateCameraToEast()
Rotate to view from the east.
const QgsVector3D origin() const
Returns the origin of the scene in map coordinates.
void rotateCameraToHome()
Rotate to diagonal view.
void rotateCameraToNorth()
Rotate to view from the north.
float distance() const
Returns distance of the camera from the point it is looking at.
friend class TestQgs3DCameraController
void rotateCameraToWest()
Rotate to view from the west.
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(Qgs3DMapScene *scene)
Constructs the camera controller with optional parent node that will take ownership.
void rotateCameraToSouth()
Rotate to view from the south.
Qgis::NavigationMode cameraNavigationMode() const
Returns the navigation mode used by the camera controller.
void cameraRotationCenterChanged(QVector3D position)
Emitted when the camera rotation center changes.
void setInputHandlersEnabled(bool enable)
Sets whether the camera controller responds to mouse and keyboard events.
void setCursorPosition(QPoint point)
Emitted when the mouse cursor position should be moved to the specified point on the map viewport.
Encapsulates camera pose in a 3D scene.
Handles coordinate transforms between two coordinate systems.
A 3D vector (similar to QVector3D) with the difference that it uses double precision instead of singl...
Definition qgsvector3d.h:30
On-screen 3D engine: it creates an OpenGL window (QWindow) and displays rendered 3D scenes there.
#define SIP_DEPRECATED
Definition qgis_sip.h:114
#define SIP_SKIP
Definition qgis_sip.h:134