QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgscamerapose.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscamerapose.cpp
3  --------------------------------------
4  Date : July 2018
5  Copyright : (C) 2018 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 #include "qgscamerapose.h"
17 
18 #include <Qt3DRender/QCamera>
19 
20 #include <QDomDocument>
21 
22 QDomElement QgsCameraPose::writeXml( QDomDocument &doc ) const
23 {
24  QDomElement elemCamera = doc.createElement( QStringLiteral( "camera-pose" ) );
25  elemCamera.setAttribute( QStringLiteral( "x" ), mCenterPoint.x() );
26  elemCamera.setAttribute( QStringLiteral( "y" ), mCenterPoint.y() );
27  elemCamera.setAttribute( QStringLiteral( "z" ), mCenterPoint.z() );
28  elemCamera.setAttribute( QStringLiteral( "dist" ), mDistanceFromCenterPoint );
29  elemCamera.setAttribute( QStringLiteral( "pitch" ), mPitchAngle );
30  elemCamera.setAttribute( QStringLiteral( "heading" ), mHeadingAngle );
31  return elemCamera;
32 }
33 
34 void QgsCameraPose::readXml( const QDomElement &elem )
35 {
36  const double x = elem.attribute( QStringLiteral( "x" ) ).toDouble();
37  const double y = elem.attribute( QStringLiteral( "y" ) ).toDouble();
38  const double z = elem.attribute( QStringLiteral( "z" ) ).toDouble();
39  mCenterPoint = QgsVector3D( x, y, z );
40 
41  mDistanceFromCenterPoint = elem.attribute( QStringLiteral( "dist" ) ).toFloat();
42  mPitchAngle = elem.attribute( QStringLiteral( "pitch" ) ).toFloat();
43  mHeadingAngle = elem.attribute( QStringLiteral( "heading" ) ).toFloat();
44 }
45 
47 {
48  // something went horribly wrong. Prevent further errors
49  if ( std::isnan( point.x() ) || std::isnan( point.y() ) || std::isnan( point.z() ) )
50  qWarning() << "Not updating camera position: it cannot be NaN!";
51  else
52  mCenterPoint = point;
53 }
54 
56 {
57  mDistanceFromCenterPoint = std::max( distance, 10.0f );
58 }
59 
60 void QgsCameraPose::setPitchAngle( float pitch )
61 {
62  // prevent going over the head
63  // prevent bug in QgsCameraPose::updateCamera when updating camera rotation.
64  // With a mPitchAngle < 0.2 or > 179.8, QQuaternion::fromEulerAngles( mPitchAngle, mHeadingAngle, 0 )
65  // will return bad rotation angle.
66  // See https://bugreports.qt.io/browse/QTBUG-72103
67  mPitchAngle = std::clamp( pitch, 0.2f, 179.8f );
68 }
69 
70 void QgsCameraPose::updateCamera( Qt3DRender::QCamera *camera )
71 {
72  // basic scene setup:
73  // - x grows to the right
74  // - z grows to the bottom
75  // - y grows towards camera
76  // so a point on the plane (x',y') is transformed to (x,-z) in our 3D world
77  camera->setUpVector( QVector3D( 0, 0, -1 ) );
78  camera->setPosition( QVector3D( mCenterPoint.x(), mDistanceFromCenterPoint + mCenterPoint.y(), mCenterPoint.z() ) );
79  camera->setViewCenter( QVector3D( mCenterPoint.x(), mCenterPoint.y(), mCenterPoint.z() ) );
80  camera->rotateAboutViewCenter( QQuaternion::fromEulerAngles( mPitchAngle, mHeadingAngle, 0 ) );
81 }
QgsVector3D::y
double y() const
Returns Y coordinate.
Definition: qgsvector3d.h:64
QgsVector3D
Class for storage of 3D vectors similar to QVector3D, with the difference that it uses double precisi...
Definition: qgsvector3d.h:31
QgsCameraPose::updateCamera
void updateCamera(Qt3DRender::QCamera *camera)
Update Qt3D camera view matrix based on the pose.
Definition: qgscamerapose.cpp:70
QgsVector3D::z
double z() const
Returns Z coordinate.
Definition: qgsvector3d.h:66
QgsCameraPose::readXml
void readXml(const QDomElement &elem)
Reads configuration from a DOM element previously written using writeXml()
Definition: qgscamerapose.cpp:34
qgscamerapose.h
QgsCameraPose::writeXml
QDomElement writeXml(QDomDocument &doc) const
Writes configuration to a new DOM element and returns it.
Definition: qgscamerapose.cpp:22
QgsCameraPose::setPitchAngle
void setPitchAngle(float pitch)
Sets pitch angle in degrees.
Definition: qgscamerapose.cpp:60
QgsCameraPose::setDistanceFromCenterPoint
void setDistanceFromCenterPoint(float distance)
Sets distance of the camera from the center point.
Definition: qgscamerapose.cpp:55
QgsVector3D::x
double x() const
Returns X coordinate.
Definition: qgsvector3d.h:62
QgsCameraPose::setCenterPoint
void setCenterPoint(const QgsVector3D &point)
Sets center point (towards which point the camera is looking)
Definition: qgscamerapose.cpp:46