QGIS API Documentation 4.3.0-Master (bf28115e945)
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::VerticalAxisInversionFlags verticalAxisInversion() const { return mVerticalAxisInversion; }
103
108 void setVerticalAxisInversion( Qgis::VerticalAxisInversionFlags 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
345 double sampleDepthBuffer( int px, int py );
346
347
348 private:
349#ifdef SIP_RUN
352#endif
353
358 void updateOrthographicProjectionPlane();
360 void updateCameraFromPose();
362 QWindow *window() const;
363
365 enum class MouseOperation
366 {
367 None = 0,
368 Translation,
369 RotationCamera,
370 RotationCenter,
371 Zoom,
372 ZoomWheel
373 };
374
375 // This list gathers all the rotation and translation operations.
376 // It is used to update the appropriate parameters when successive
377 // translation and rotation happen.
378 // clang-format off
379 const QList<MouseOperation> mTranslateOrRotate = {
380 MouseOperation::Translation,
381 MouseOperation::RotationCamera,
382 MouseOperation::RotationCenter
383 };
384 // clang-format on
385
386 // check that current sequence (current operation and new operation) is a rotation or translation
387 bool isATranslationRotationSequence( MouseOperation newOperation ) const;
388
389 void setMouseParameters( const MouseOperation &newOperation, const QPoint &clickPoint = QPoint() );
390
396 void rotateToRespectingTerrain( float pitch, float yaw );
397
398 signals:
401
404
408 void cameraMovementSpeedChanged( double speed );
409
414 void setCursorPosition( QPoint point );
415
421
426 void cameraRotationCenterChanged( QVector3D position );
427
433
434 private slots:
435 void onPositionChanged( Qt3DInput::QMouseEvent *mouse );
436 void onWheel( Qt3DInput::QWheelEvent *wheel );
437 void onMousePressed( Qt3DInput::QMouseEvent *mouse );
438 void onMouseReleased( Qt3DInput::QMouseEvent *mouse );
439 void applyFlyModeKeyMovements();
440
441 private:
442 // All three methods return true if event is handled
443 bool onKeyPressedFlyNavigation( QKeyEvent *event );
444 bool onKeyPressedTerrainNavigation( QKeyEvent *event );
445 bool onKeyPressedGlobeTerrainNavigation( QKeyEvent *event );
446 void onPositionChangedFlyNavigation( Qt3DInput::QMouseEvent *mouse );
447 void onPositionChangedTerrainNavigation( Qt3DInput::QMouseEvent *mouse );
448 void onPositionChangedGlobeTerrainNavigation( Qt3DInput::QMouseEvent *mouse );
449
450 void handleTerrainNavigationWheelZoom();
451
452 // Returns the average depth of all non void pixels
453 double depthBufferNonVoidAverage();
454
455#ifndef SIP_RUN
457 bool screenPointToWorldPos( QPoint position, double &depth, QVector3D &worldPosition );
458#endif
459
460 // Moves given point (in ECEF) by specified lat/lon angle difference (in degrees) and returns new ECEF point
461 QgsVector3D moveGeocentricPoint( const QgsVector3D &point, double latDiff, double lonDiff );
462
464 Qgs3DMapScene *mScene = nullptr;
465
467 Qt3DRender::QCamera *mCamera = nullptr;
468
470 QgsCameraPose mCameraPose;
471
473 QPoint mMousePos;
474
476 QPoint mClickPoint;
477
478 // false when no depth buffer captured or new capture requested and not yet done.
479 bool mDepthBufferIsReady = false;
480 QImage mDepthBufferImage;
481 // -1 when unset
482 // TODO: Change to std::optional<double>
483 double mDepthBufferNonVoidAverage = -1;
484 // nullptr when !mDepthBufferIsReady
485 std::unique_ptr<Qt3DRender::QCamera> mDepthBufferCamera;
486
487 std::unique_ptr<Qt3DRender::QCamera> mCameraBefore;
488
489 bool mRotationCenterCalculated = false;
490 QVector3D mRotationCenter;
491 double mRotationDistanceFromCenter = 0;
492 float mRotationPitch = 0;
493 float mRotationYaw = 0;
494
495 bool mDragPointCalculated = false;
496 QVector3D mDragPoint;
497 double mDragDepth = 0;
498
499 bool mZoomPointCalculated = false;
500 QVector3D mZoomPoint;
501
502 // used for globe
503 QgsVector3D mMousePressViewCenter;
504 QgsCoordinateTransform mGlobeCrsToLatLon;
505
506 Qt3DInput::QMouseHandler *mMouseHandler = nullptr;
507 Qt3DInput::QKeyboardHandler *mKeyboardHandler = nullptr;
508 bool mInputHandlersEnabled = true;
511 double mCameraMovementSpeed = 5.0;
512
513 QSet<int> mDepressedKeys;
514 bool mCaptureFpsMouseMovements = false;
515 bool mIgnoreNextMouseMove = false;
516 QTimer *mFpsNavTimer = nullptr;
517
518 double mCumulatedWheelY = 0;
519
520 MouseOperation mCurrentOperation = MouseOperation::None;
521
522 // 3D world's origin in map coordinates
523 QgsVector3D mOrigin;
524
526 bool mCameraChanged = false;
527
528 // To test the cameracontroller
529 friend class TestQgs3DRendering;
531};
532
533#endif // QGSCAMERACONTROLLER_H
@ WhenPivoting
When pivoting camera around point in terrain.
Definition qgis.h:4518
@ WhenRotatingDragging
When rotating camera around self with mouse captured.
Definition qgis.h:4516
NavigationMode
The navigation mode used by 3D cameras.
Definition qgis.h:4490
@ TerrainBased
The default navigation based on the terrain.
Definition qgis.h:4491
QFlags< VerticalAxisInversion > VerticalAxisInversionFlags
Definition qgis.h:4527
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.
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.
Qgis::VerticalAxisInversionFlags verticalAxisInversion() const
Returns the vertical axis inversion behavior.
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 depthBufferReady()
Emitted after the depth buffer has been captured and is ready to sample.
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