QGIS API Documentation 4.1.0-Master (60fea48833c)
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
344 void updateCameraFromPose();
346 QWindow *window() const;
347
349 enum class MouseOperation
350 {
351 None = 0, // no operation
352 Translation, // left button pressed, no modifier
353 RotationCamera, // left button pressed + ctrl modifier
354 RotationCenter, // left button pressed + shift modifier
355 Zoom, // right button pressed
356 ZoomWheel // mouse wheel scroll
357 };
358
359 // This list gathers all the rotation and translation operations.
360 // It is used to update the appropriate parameters when successive
361 // translation and rotation happen.
362 // clang-format off
363 const QList<MouseOperation> mTranslateOrRotate = {
364 MouseOperation::Translation,
365 MouseOperation::RotationCamera,
366 MouseOperation::RotationCenter
367 };
368 // clang-format on
369
370 // check that current sequence (current operation and new operation) is a rotation or translation
371 bool isATranslationRotationSequence( MouseOperation newOperation ) const;
372
373 void setMouseParameters( const MouseOperation &newOperation, const QPoint &clickPoint = QPoint() );
374
380 void rotateToRespectingTerrain( float pitch, float yaw );
381
382 signals:
385
388
392 void cameraMovementSpeedChanged( double speed );
393
398 void setCursorPosition( QPoint point );
399
405
410 void cameraRotationCenterChanged( QVector3D position );
411
412 private slots:
413 void onPositionChanged( Qt3DInput::QMouseEvent *mouse );
414 void onWheel( Qt3DInput::QWheelEvent *wheel );
415 void onMousePressed( Qt3DInput::QMouseEvent *mouse );
416 void onMouseReleased( Qt3DInput::QMouseEvent *mouse );
417 void applyFlyModeKeyMovements();
418
419 private:
420 // All three methods return true if event is handled
421 bool onKeyPressedFlyNavigation( QKeyEvent *event );
422 bool onKeyPressedTerrainNavigation( QKeyEvent *event );
423 bool onKeyPressedGlobeTerrainNavigation( QKeyEvent *event );
424 void onPositionChangedFlyNavigation( Qt3DInput::QMouseEvent *mouse );
425 void onPositionChangedTerrainNavigation( Qt3DInput::QMouseEvent *mouse );
426 void onPositionChangedGlobeTerrainNavigation( Qt3DInput::QMouseEvent *mouse );
427
428 void handleTerrainNavigationWheelZoom();
429
436 double sampleDepthBuffer( int px, int py );
437
438 // Returns the average depth of all non void pixels
439 double depthBufferNonVoidAverage();
440
441#ifndef SIP_RUN
443 bool screenPointToWorldPos( QPoint position, double &depth, QVector3D &worldPosition );
444#endif
445
446 // Moves given point (in ECEF) by specified lat/lon angle difference (in degrees) and returns new ECEF point
447 QgsVector3D moveGeocentricPoint( const QgsVector3D &point, double latDiff, double lonDiff );
448
450 Qgs3DMapScene *mScene = nullptr;
451
453 Qt3DRender::QCamera *mCamera = nullptr;
454
456 QgsCameraPose mCameraPose;
457
459 QPoint mMousePos;
460
462 QPoint mClickPoint;
463
464 // false when no depth buffer captured or new capture requested and not yet done.
465 bool mDepthBufferIsReady = false;
466 QImage mDepthBufferImage;
467 // -1 when unset
468 // TODO: Change to std::optional<double>
469 double mDepthBufferNonVoidAverage = -1;
470 // nullptr when !mDepthBufferIsReady
471 std::unique_ptr<Qt3DRender::QCamera> mDepthBufferCamera;
472
473 std::unique_ptr<Qt3DRender::QCamera> mCameraBefore;
474
475 bool mRotationCenterCalculated = false;
476 QVector3D mRotationCenter;
477 double mRotationDistanceFromCenter = 0;
478 float mRotationPitch = 0;
479 float mRotationYaw = 0;
480
481 bool mDragPointCalculated = false;
482 QVector3D mDragPoint;
483 double mDragDepth = 0;
484
485 bool mZoomPointCalculated = false;
486 QVector3D mZoomPoint;
487
488 // used for globe
489 QgsVector3D mMousePressViewCenter;
490 QgsCoordinateTransform mGlobeCrsToLatLon;
491
492 Qt3DInput::QMouseHandler *mMouseHandler = nullptr;
493 Qt3DInput::QKeyboardHandler *mKeyboardHandler = nullptr;
494 bool mInputHandlersEnabled = true;
497 double mCameraMovementSpeed = 5.0;
498
499 QSet<int> mDepressedKeys;
500 bool mCaptureFpsMouseMovements = false;
501 bool mIgnoreNextMouseMove = false;
502 QTimer *mFpsNavTimer = nullptr;
503
504 double mCumulatedWheelY = 0;
505
506 MouseOperation mCurrentOperation = MouseOperation::None;
507
508 // 3D world's origin in map coordinates
509 QgsVector3D mOrigin;
510
512 bool mCameraChanged = false;
513
514 // To test the cameracontroller
515 friend class TestQgs3DRendering;
517};
518
519#endif // QGSCAMERACONTROLLER_H
VerticalAxisInversion
Vertical axis inversion options for 3D views.
Definition qgis.h:4309
@ WhenDragging
Invert vertical axis movements when dragging in first person modes.
Definition qgis.h:4311
NavigationMode
The navigation mode used by 3D cameras.
Definition qgis.h:4284
@ TerrainBased
The default navigation based on the terrain.
Definition qgis.h:4285
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