1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Data Visualization module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 or (at your option) any later version
20** approved by the KDE Free Qt Foundation. The licenses are as published by
21** the Free Software Foundation and appearing in the file LICENSE.GPL3
22** included in the packaging of this file. Please review the following
23** information to ensure the GNU General Public License requirements will
24** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25**
26** $QT_END_LICENSE$
27**
28****************************************************************************/
29
30#include "camerahelper_p.h"
31
32#include <QtCore/qmath.h>
33#include <QtGui/QMatrix4x4>
34
35QT_BEGIN_NAMESPACE_DATAVISUALIZATION
36
37CameraHelper::CameraHelper(QObject *parent) :
38 QObject(parent),
39 m_position(0, 0.25, 3),
40 m_target(0, 0, 0),
41 m_up(0, 1, 0),
42 m_previousMousePos(0,0),
43 m_xRotation(0),
44 m_yRotation(0),
45 m_defaultXRotation(0),
46 m_defaultYRotation(0),
47 m_rotationSpeed(100)
48{
49}
50
51CameraHelper::~CameraHelper()
52{
53}
54
55void CameraHelper::setRotationSpeed(int speed)
56{
57 // increase for faster rotation
58 m_rotationSpeed = speed;
59}
60
61void CameraHelper::setCameraRotation(const QPointF &rotation)
62{
63 m_xRotation = rotation.x();
64 m_defaultXRotation = m_xRotation;
65 m_yRotation = rotation.y();
66 m_defaultYRotation = m_yRotation;
67}
68
69void CameraHelper::setDefaultCameraOrientation(const QVector3D &defaultPosition,
70 const QVector3D &defaultTarget,
71 const QVector3D &defaultUp)
72{
73 m_position = defaultPosition;
74 m_target = defaultTarget;
75 m_up = defaultUp;
76}
77
78QMatrix4x4 CameraHelper::calculateViewMatrix(const QPoint &mousePos, int zoom,
79 int screenWidth, int screenHeight, bool showUnder)
80{
81 QMatrix4x4 viewMatrix;
82 GLfloat lowerLimit = 0.0f;
83
84 if (showUnder)
85 lowerLimit = -90.0f;
86
87 // Calculate mouse movement since last frame
88 GLfloat mouseMoveX = GLfloat(m_previousMousePos.x() - mousePos.x())
89 / (screenWidth / m_rotationSpeed);
90 GLfloat mouseMoveY = GLfloat(m_previousMousePos.y() - mousePos.y())
91 / (screenHeight / m_rotationSpeed);
92 // Apply to rotations
93 m_xRotation -= mouseMoveX;
94 m_yRotation -= mouseMoveY;
95 // Reset at 360 in x and limit to 0...90 in y
96 if (qAbs(t: m_xRotation) >= 360.0f)
97 m_xRotation = 0.0f;
98 if (m_yRotation >= 90.0f)
99 m_yRotation = 90.0f;
100 else if (m_yRotation <= lowerLimit)
101 m_yRotation = lowerLimit;
102
103 // Apply to view matrix
104 viewMatrix.lookAt(eye: m_position, center: m_target, up: m_up);
105 // Compensate for translation (if m_target is off origin)
106 viewMatrix.translate(x: m_target.x(), y: m_target.y(), z: m_target.z());
107 // Apply rotations
108 // Handle x and z rotation when y -angle is other than 0
109 viewMatrix.rotate(angle: m_xRotation, x: 0, y: qCos(v: qDegreesToRadians(degrees: m_yRotation)),
110 z: qSin(v: qDegreesToRadians(degrees: m_yRotation)));
111 // y rotation is always "clean"
112 viewMatrix.rotate(angle: m_yRotation, x: 1.0f, y: 0.0f, z: 0.0f);
113 // handle zoom by scaling
114 viewMatrix.scale(factor: (GLfloat)zoom / 100.0f);
115 // Compensate for translation (if m_target is off origin)
116 viewMatrix.translate(x: -m_target.x(), y: -m_target.y(), z: -m_target.z());
117
118 m_previousMousePos = mousePos;
119 return viewMatrix;
120}
121
122QVector3D CameraHelper::calculateLightPosition(const QVector3D &lightPosition,
123 GLfloat fixedRotation, GLfloat distanceModifier)
124{
125 // Move light with camera
126 QVector3D newLightPosition;
127 GLfloat radiusFactor = lightPosition.z() * (1.5f + distanceModifier); // for making sure light is outside the scene at its lowest point
128 GLfloat xAngle;
129 GLfloat yAngle;
130 if (!fixedRotation) {
131 xAngle = qDegreesToRadians(degrees: m_xRotation);
132 yAngle = qDegreesToRadians(degrees: m_yRotation);
133 } else {
134 xAngle = qDegreesToRadians(degrees: fixedRotation);
135 yAngle = 0;
136 }
137 GLfloat radius = (radiusFactor + lightPosition.y()); // set radius to match the highest height of the light
138 GLfloat zPos = radius * qCos(v: xAngle) * qCos(v: yAngle);
139 GLfloat xPos = radius * qSin(v: xAngle) * qCos(v: yAngle);
140 GLfloat yPos = (radiusFactor + lightPosition.y()) * qSin(v: yAngle);
141 // Keep light in the set position in relation to camera
142 newLightPosition = QVector3D(-xPos + lightPosition.x(),
143 yPos + lightPosition.y(),
144 zPos + lightPosition.z());
145 return newLightPosition;
146}
147
148void CameraHelper::updateMousePos(const QPoint &mousePos)
149{
150 m_previousMousePos = mousePos;
151 // if mouse position is set to (0, 0), reset rotations
152 if (QPoint(0, 0) == mousePos) {
153 m_xRotation = m_defaultXRotation;
154 m_yRotation = m_defaultYRotation;
155 }
156}
157
158QPointF CameraHelper::getCameraRotations()
159{
160 QPointF rotations(m_xRotation, m_yRotation);
161 return rotations;
162}
163
164void CameraHelper::setCameraPreset(Q3DCamera::CameraPreset preset)
165{
166 switch (preset) {
167 case Q3DCamera::CameraPresetFrontLow: {
168 CameraHelper::setCameraRotation(QPointF(0.0f, 0.0f));
169 break;
170 }
171 case Q3DCamera::CameraPresetFront: {
172 CameraHelper::setCameraRotation(QPointF(0.0f, 22.5f));
173 break;
174 }
175 case Q3DCamera::CameraPresetFrontHigh: {
176 CameraHelper::setCameraRotation(QPointF(0.0f, 45.0f));
177 break;
178 }
179 case Q3DCamera::CameraPresetLeftLow: {
180 CameraHelper::setCameraRotation(QPointF(90.0f, 0.0f));
181 break;
182 }
183 case Q3DCamera::CameraPresetLeft: {
184 CameraHelper::setCameraRotation(QPointF(90.0f, 22.5f));
185 break;
186 }
187 case Q3DCamera::CameraPresetLeftHigh: {
188 CameraHelper::setCameraRotation(QPointF(90.0f, 45.0f));
189 break;
190 }
191 case Q3DCamera::CameraPresetRightLow: {
192 CameraHelper::setCameraRotation(QPointF(-90.0f, 0.0f));
193 break;
194 }
195 case Q3DCamera::CameraPresetRight: {
196 CameraHelper::setCameraRotation(QPointF(-90.0f, 22.5f));
197 break;
198 }
199 case Q3DCamera::CameraPresetRightHigh: {
200 CameraHelper::setCameraRotation(QPointF(-90.0f, 45.0f));
201 break;
202 }
203 case Q3DCamera::CameraPresetBehindLow: {
204 CameraHelper::setCameraRotation(QPointF(180.0f, 0.0f));
205 break;
206 }
207 case Q3DCamera::CameraPresetBehind: {
208 CameraHelper::setCameraRotation(QPointF(180.0f, 22.5f));
209 break;
210 }
211 case Q3DCamera::CameraPresetBehindHigh: {
212 CameraHelper::setCameraRotation(QPointF(180.0f, 45.0f));
213 break;
214 }
215 case Q3DCamera::CameraPresetIsometricLeft: {
216 CameraHelper::setCameraRotation(QPointF(45.0f, 22.5f));
217 break;
218 }
219 case Q3DCamera::CameraPresetIsometricLeftHigh: {
220 CameraHelper::setCameraRotation(QPointF(45.0f, 45.0f));
221 break;
222 }
223 case Q3DCamera::CameraPresetIsometricRight: {
224 CameraHelper::setCameraRotation(QPointF(-45.0f, 22.5f));
225 break;
226 }
227 case Q3DCamera::CameraPresetIsometricRightHigh: {
228 CameraHelper::setCameraRotation(QPointF(-45.0f, 45.0f));
229 break;
230 }
231 case Q3DCamera::CameraPresetDirectlyAbove: {
232 CameraHelper::setCameraRotation(QPointF(0.0f, 90.0f));
233 break;
234 }
235 case Q3DCamera::CameraPresetDirectlyAboveCW45: {
236 CameraHelper::setCameraRotation(QPointF(-45.0f, 90.0f));
237 break;
238 }
239 case Q3DCamera::CameraPresetDirectlyAboveCCW45: {
240 CameraHelper::setCameraRotation(QPointF(45.0f, 90.0f));
241 break;
242 }
243 case Q3DCamera::CameraPresetFrontBelow: {
244 CameraHelper::setCameraRotation(QPointF(0.0f, -45.0f));
245 break;
246 }
247 case Q3DCamera::CameraPresetLeftBelow: {
248 CameraHelper::setCameraRotation(QPointF(90.0f, -45.0f));
249 break;
250 }
251 case Q3DCamera::CameraPresetRightBelow: {
252 CameraHelper::setCameraRotation(QPointF(-90.0f, -45.0f));
253 break;
254 }
255 case Q3DCamera::CameraPresetBehindBelow: {
256 CameraHelper::setCameraRotation(QPointF(180.0f, -45.0f));
257 break;
258 }
259 case Q3DCamera::CameraPresetDirectlyBelow: {
260 CameraHelper::setCameraRotation(QPointF(0.0f, -90.0f));
261 break;
262 }
263 default:
264 break;
265 }
266}
267
268QT_END_NAMESPACE_DATAVISUALIZATION
269

source code of qtdatavis3d/src/datavisualization/utils/camerahelper.cpp