QGIS API Documentation 3.99.0-Master (a8882ad4560)
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 const QList<MouseOperation> mTranslateOrRotate = {
363 MouseOperation::Translation,
364 MouseOperation::RotationCamera,
365 MouseOperation::RotationCenter
366 };
367
368 // check that current sequence (current operation and new operation) is a rotation or translation
369 bool isATranslationRotationSequence( MouseOperation newOperation ) const;
370
371 void setMouseParameters( const MouseOperation &newOperation, const QPoint &clickPoint = QPoint() );
372
378 void rotateToRespectingTerrain( float pitch, float yaw );
379
380 signals:
383
386
390 void cameraMovementSpeedChanged( double speed );
391
396 void setCursorPosition( QPoint point );
397
403
408 void cameraRotationCenterChanged( QVector3D position );
409
410 private slots:
411 void onPositionChanged( Qt3DInput::QMouseEvent *mouse );
412 void onWheel( Qt3DInput::QWheelEvent *wheel );
413 void onMousePressed( Qt3DInput::QMouseEvent *mouse );
414 void onMouseReleased( Qt3DInput::QMouseEvent *mouse );
415 void applyFlyModeKeyMovements();
416
417 private:
418 // All three methods return true if event is handled
419 bool onKeyPressedFlyNavigation( QKeyEvent *event );
420 bool onKeyPressedTerrainNavigation( QKeyEvent *event );
421 bool onKeyPressedGlobeTerrainNavigation( QKeyEvent *event );
422 void onPositionChangedFlyNavigation( Qt3DInput::QMouseEvent *mouse );
423 void onPositionChangedTerrainNavigation( Qt3DInput::QMouseEvent *mouse );
424 void onPositionChangedGlobeTerrainNavigation( Qt3DInput::QMouseEvent *mouse );
425
426 void handleTerrainNavigationWheelZoom();
427
434 double sampleDepthBuffer( int px, int py );
435
436 // Returns the average depth of all non void pixels
437 double depthBufferNonVoidAverage();
438
439#ifndef SIP_RUN
441 bool screenPointToWorldPos( QPoint position, double &depth, QVector3D &worldPosition );
442#endif
443
444 // Moves given point (in ECEF) by specified lat/lon angle difference (in degrees) and returns new ECEF point
445 QgsVector3D moveGeocentricPoint( const QgsVector3D &point, double latDiff, double lonDiff );
446
448 Qgs3DMapScene *mScene = nullptr;
449
451 Qt3DRender::QCamera *mCamera = nullptr;
452
454 QgsCameraPose mCameraPose;
455
457 QPoint mMousePos;
458
460 QPoint mClickPoint;
461
462 // false when no depth buffer captured or new capture requested and not yet done.
463 bool mDepthBufferIsReady = false;
464 QImage mDepthBufferImage;
465 // -1 when unset
466 // TODO: Change to std::optional<double>
467 double mDepthBufferNonVoidAverage = -1;
468 // nullptr when !mDepthBufferIsReady
469 std::unique_ptr<Qt3DRender::QCamera> mDepthBufferCamera;
470
471 std::unique_ptr<Qt3DRender::QCamera> mCameraBefore;
472
473 bool mRotationCenterCalculated = false;
474 QVector3D mRotationCenter;
475 double mRotationDistanceFromCenter = 0;
476 float mRotationPitch = 0;
477 float mRotationYaw = 0;
478
479 bool mDragPointCalculated = false;
480 QVector3D mDragPoint;
481 double mDragDepth = 0;
482
483 bool mZoomPointCalculated = false;
484 QVector3D mZoomPoint;
485
486 // used for globe
487 QgsVector3D mMousePressViewCenter;
488 QgsCoordinateTransform mGlobeCrsToLatLon;
489
490 Qt3DInput::QMouseHandler *mMouseHandler = nullptr;
491 Qt3DInput::QKeyboardHandler *mKeyboardHandler = nullptr;
492 bool mInputHandlersEnabled = true;
495 double mCameraMovementSpeed = 5.0;
496
497 QSet<int> mDepressedKeys;
498 bool mCaptureFpsMouseMovements = false;
499 bool mIgnoreNextMouseMove = false;
500 QTimer *mFpsNavTimer = nullptr;
501
502 double mCumulatedWheelY = 0;
503
504 MouseOperation mCurrentOperation = MouseOperation::None;
505
506 // 3D world's origin in map coordinates
507 QgsVector3D mOrigin;
508
510 bool mCameraChanged = false;
511
512 // To test the cameracontroller
513 friend class TestQgs3DRendering;
515};
516
517#endif // QGSCAMERACONTROLLER_H
VerticalAxisInversion
Vertical axis inversion options for 3D views.
Definition qgis.h:4227
@ WhenDragging
Invert vertical axis movements when dragging in first person modes.
Definition qgis.h:4229
NavigationMode
The navigation mode used by 3D cameras.
Definition qgis.h:4202
@ TerrainBased
The default navigation based on the terrain.
Definition qgis.h:4203
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: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