QGIS API Documentation 4.1.0-Master (3b8ef1f72a3)
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;
51class QgsCrossSection;
52
57#ifndef SIP_RUN
58class _3D_EXPORT QgsCameraController : public Qt3DCore::QEntity
59{
60#else
61class _3D_EXPORT QgsCameraController : public QObject
62{
63#endif
64
65 Q_OBJECT
66 public:
70
71#ifndef SIP_RUN
72
77 Qt3DRender::QCamera *camera() const { return mCamera; }
78#endif
79
84 Qgis::NavigationMode cameraNavigationMode() const { return mCameraNavigationMode; }
85
90 double cameraMovementSpeed() const { return mCameraMovementSpeed; }
91
96 void setCameraMovementSpeed( double movementSpeed );
97
102 Qgis::VerticalAxisInversion verticalAxisInversion() const { return mVerticalAxisInversion; }
103
108 void setVerticalAxisInversion( Qgis::VerticalAxisInversion inversion );
109
111 void frameTriggered( float dt );
112
114 void resetView( float distance );
115
117 void setViewFromTop( float worldX, float worldY, float distance, float yaw = 0 );
118
120 QgsVector3D lookingAtPoint() const;
121
128 void setLookingAtPoint( const QgsVector3D &point, float distance, float pitch, float yaw );
129
134 QgsVector3D lookingAtMapPoint() const;
135
140 void setLookingAtMapPoint( const QgsVector3D &point, float distance, float pitch, float yaw );
141
146 void setCameraPose( const QgsCameraPose &camPose, bool force = false );
147
152 QgsCameraPose cameraPose() const { return mCameraPose; }
153
159 float distance() const { return mCameraPose.distanceFromCenterPoint(); }
160
166 float pitch() const { return mCameraPose.pitchAngle(); }
167
173 float yaw() const { return mCameraPose.headingAngle(); }
174
176 QDomElement writeXml( QDomDocument &doc ) const;
178 void readXml( const QDomElement &elem, QgsVector3D savedOrigin );
179
181 void zoom( float factor );
183 void tiltUpAroundViewCenter( float deltaPitch );
185 void rotateAroundViewCenter( float deltaYaw );
187 void setCameraHeadingAngle( float angle );
189 void moveView( float tx, float ty );
190
195 void walkView( double tx, double ty, double tz );
196
203 void rotateCamera( float diffPitch, float diffYaw );
204
210 void rotateCameraAroundPivot( float newPitch, float newHeading, const QVector3D &pivotPoint );
211
219 Q_DECL_DEPRECATED void zoomCameraAroundPivot( const QVector3D &oldCameraPosition, double zoomFactor, const QVector3D &pivotPoint ) SIP_DEPRECATED;
220
227 void zoomCameraAroundPivot( const QVector3D &oldCameraPosition, double oldDistanceFromCenterPoint, double zoomFactor, const QVector3D &pivotPoint );
228
233 bool keyboardEventFilter( QKeyEvent *event );
234
241 void setOrigin( const QgsVector3D &origin );
242
247 void setInputHandlersEnabled( bool enable ) { mInputHandlersEnabled = enable; }
248
253 bool hasInputHandlersEnabled() const { return mInputHandlersEnabled; }
254
261 void globeMoveCenterPoint( double latDiff, double lonDiff );
262
268 void globeZoom( float factor );
269
274 void globeUpdatePitchAngle( float angleDiff );
275
280 void globeUpdateHeadingAngle( float angleDiff );
281
287 void resetGlobe( float distance, double lat = 0, double lon = 0 );
288
293 const QgsVector3D origin() const { return mOrigin; }
294
300 void setCrossSectionSideView( const QgsCrossSection &crossSection );
301
302 // Convenience methods to set camera view to standard positions
304 void rotateCameraToHome() { rotateToRespectingTerrain( 45.0f, 45.0f ); }
306 void rotateCameraToTop() { rotateToRespectingTerrain( 0.0f, 0.0f ); }
308 void rotateCameraToNorth() { rotateToRespectingTerrain( 90.0f, 180.0f ); }
310 void rotateCameraToEast() { rotateToRespectingTerrain( 90.0f, 90.0f ); }
312 void rotateCameraToSouth() { rotateToRespectingTerrain( 90.0f, 0.0f ); }
314 void rotateCameraToWest() { rotateToRespectingTerrain( 90.0f, -90.0f ); }
316 void rotateCameraToBottom() { rotateToRespectingTerrain( 180.0f, 0.0f ); }
317
318 public slots:
319
324 void setCameraNavigationMode( Qgis::NavigationMode navigationMode );
325
330 void depthBufferCaptured( const QImage &depthImage );
331
336 void moveCenterPoint( const QVector3D &posDiff );
337
338 private:
339#ifdef SIP_RUN
342#endif
343
348 void updateOrthographicProjectionPlane();
350 void updateCameraFromPose();
352 QWindow *window() const;
353
355 enum class MouseOperation
356 {
357 None = 0, // no operation
358 Translation, // left button pressed, no modifier
359 RotationCamera, // left button pressed + ctrl modifier
360 RotationCenter, // left button pressed + shift modifier
361 Zoom, // right button pressed
362 ZoomWheel // mouse wheel scroll
363 };
364
365 // This list gathers all the rotation and translation operations.
366 // It is used to update the appropriate parameters when successive
367 // translation and rotation happen.
368 // clang-format off
369 const QList<MouseOperation> mTranslateOrRotate = {
370 MouseOperation::Translation,
371 MouseOperation::RotationCamera,
372 MouseOperation::RotationCenter
373 };
374 // clang-format on
375
376 // check that current sequence (current operation and new operation) is a rotation or translation
377 bool isATranslationRotationSequence( MouseOperation newOperation ) const;
378
379 void setMouseParameters( const MouseOperation &newOperation, const QPoint &clickPoint = QPoint() );
380
386 void rotateToRespectingTerrain( float pitch, float yaw );
387
388 signals:
391
394
398 void cameraMovementSpeedChanged( double speed );
399
404 void setCursorPosition( QPoint point );
405
411
416 void cameraRotationCenterChanged( QVector3D position );
417
418 private slots:
419 void onPositionChanged( Qt3DInput::QMouseEvent *mouse );
420 void onWheel( Qt3DInput::QWheelEvent *wheel );
421 void onMousePressed( Qt3DInput::QMouseEvent *mouse );
422 void onMouseReleased( Qt3DInput::QMouseEvent *mouse );
423 void applyFlyModeKeyMovements();
424
425 private:
426 // All three methods return true if event is handled
427 bool onKeyPressedFlyNavigation( QKeyEvent *event );
428 bool onKeyPressedTerrainNavigation( QKeyEvent *event );
429 bool onKeyPressedGlobeTerrainNavigation( QKeyEvent *event );
430 void onPositionChangedFlyNavigation( Qt3DInput::QMouseEvent *mouse );
431 void onPositionChangedTerrainNavigation( Qt3DInput::QMouseEvent *mouse );
432 void onPositionChangedGlobeTerrainNavigation( Qt3DInput::QMouseEvent *mouse );
433
434 void handleTerrainNavigationWheelZoom();
435
442 double sampleDepthBuffer( int px, int py );
443
444 // Returns the average depth of all non void pixels
445 double depthBufferNonVoidAverage();
446
447#ifndef SIP_RUN
449 bool screenPointToWorldPos( QPoint position, double &depth, QVector3D &worldPosition );
450#endif
451
452 // Moves given point (in ECEF) by specified lat/lon angle difference (in degrees) and returns new ECEF point
453 QgsVector3D moveGeocentricPoint( const QgsVector3D &point, double latDiff, double lonDiff );
454
456 Qgs3DMapScene *mScene = nullptr;
457
459 Qt3DRender::QCamera *mCamera = nullptr;
460
462 QgsCameraPose mCameraPose;
463
465 QPoint mMousePos;
466
468 QPoint mClickPoint;
469
470 // false when no depth buffer captured or new capture requested and not yet done.
471 bool mDepthBufferIsReady = false;
472 QImage mDepthBufferImage;
473 // -1 when unset
474 // TODO: Change to std::optional<double>
475 double mDepthBufferNonVoidAverage = -1;
476 // nullptr when !mDepthBufferIsReady
477 std::unique_ptr<Qt3DRender::QCamera> mDepthBufferCamera;
478
479 std::unique_ptr<Qt3DRender::QCamera> mCameraBefore;
480
481 bool mRotationCenterCalculated = false;
482 QVector3D mRotationCenter;
483 double mRotationDistanceFromCenter = 0;
484 float mRotationPitch = 0;
485 float mRotationYaw = 0;
486
487 bool mDragPointCalculated = false;
488 QVector3D mDragPoint;
489 double mDragDepth = 0;
490
491 bool mZoomPointCalculated = false;
492 QVector3D mZoomPoint;
493
494 // used for globe
495 QgsVector3D mMousePressViewCenter;
496 QgsCoordinateTransform mGlobeCrsToLatLon;
497
498 Qt3DInput::QMouseHandler *mMouseHandler = nullptr;
499 Qt3DInput::QKeyboardHandler *mKeyboardHandler = nullptr;
500 bool mInputHandlersEnabled = true;
503 double mCameraMovementSpeed = 5.0;
504
505 QSet<int> mDepressedKeys;
506 bool mCaptureFpsMouseMovements = false;
507 bool mIgnoreNextMouseMove = false;
508 QTimer *mFpsNavTimer = nullptr;
509
510 double mCumulatedWheelY = 0;
511
512 MouseOperation mCurrentOperation = MouseOperation::None;
513
514 // 3D world's origin in map coordinates
515 QgsVector3D mOrigin;
516
518 bool mCameraChanged = false;
519
520 // To test the cameracontroller
521 friend class TestQgs3DRendering;
523};
524
525#endif // QGSCAMERACONTROLLER_H
VerticalAxisInversion
Vertical axis inversion options for 3D views.
Definition qgis.h:4382
@ WhenDragging
Invert vertical axis movements when dragging in first person modes.
Definition qgis.h:4384
NavigationMode
The navigation mode used by 3D cameras.
Definition qgis.h:4357
@ TerrainBased
The default navigation based on the terrain.
Definition qgis.h:4358
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.
Encapsulates the definition of a cross section in 3D map coordinates.
A 3D vector (similar to QVector3D) with the difference that it uses double precision instead of singl...
Definition qgsvector3d.h:33
On-screen 3D engine: it creates an OpenGL window (QWindow) and displays rendered 3D scenes there.
#define SIP_DEPRECATED
Definition qgis_sip.h:113
#define SIP_SKIP
Definition qgis_sip.h:133