1/****************************************************************************
2**
3** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
4** Contact: http://www.qt-project.org/legal
5**
6** This file is part of the Qt3D module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL3$
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 http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPLv3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or later as published by the Free
28** Software Foundation and appearing in the file LICENSE.GPL included in
29** the packaging of this file. Please review the following information to
30** ensure the GNU General Public License version 2.0 requirements will be
31** met: http://www.gnu.org/licenses/gpl-2.0.html.
32**
33** $QT_END_LICENSE$
34**
35****************************************************************************/
36
37#include "qorbitcameracontroller.h"
38#include "qorbitcameracontroller_p.h"
39
40#include <Qt3DRender/QCamera>
41
42QT_BEGIN_NAMESPACE
43
44namespace Qt3DExtras {
45
46QOrbitCameraControllerPrivate::QOrbitCameraControllerPrivate()
47 : m_zoomInLimit(2.0f)
48{}
49
50/*!
51 \class Qt3DExtras::QOrbitCameraController
52 \ingroup qt3d-extras-cameracontrollers
53 \brief The QOrbitCameraController class allows controlling the scene camera along orbital path.
54 \inmodule Qt3DExtras
55 \since 5.7
56 \inherits Qt3DCore::QEntity
57
58 The controls are:
59 \table
60 \header
61 \li Input
62 \li Action
63 \row
64 \li Left mouse button
65 \li While the left mouse button is pressed, mouse movement along x-axis moves the camera
66 left and right and movement along y-axis moves it up and down.
67 \row
68 \li Right mouse button
69 \li While the right mouse button is pressed, mouse movement along x-axis pans the camera
70 around the camera view center and movement along y-axis tilts it around the camera
71 view center.
72 \row
73 \li Both left and right mouse button
74 \li While both the left and the right mouse button are pressed, mouse movement along y-axis
75 zooms the camera in and out without changing the view center.
76 \row
77 \li Mouse scroll wheel
78 \li Zooms the camera in and out without changing the view center.
79 \row
80 \li Arrow keys
81 \li Move the camera vertically and horizontally relative to camera viewport.
82 \row
83 \li Page up and page down keys
84 \li Move the camera forwards and backwards.
85 \row
86 \li Shift key
87 \li Changes the behavior of the up and down arrow keys to zoom the camera in and out
88 without changing the view center. The other movement keys are disabled.
89 \row
90 \li Alt key
91 \li Changes the behovior of the arrow keys to pan and tilt the camera around the view
92 center. Disables the page up and page down keys.
93 \row
94 \li Escape
95 \li Moves the camera so that entire scene is visible in the camera viewport.
96 \endtable
97*/
98
99QOrbitCameraController::QOrbitCameraController(Qt3DCore::QNode *parent)
100 : QOrbitCameraController(*new QOrbitCameraControllerPrivate, parent)
101{
102}
103
104/*! \internal
105 */
106QOrbitCameraController::QOrbitCameraController(QOrbitCameraControllerPrivate &dd, Qt3DCore::QNode *parent)
107 : QAbstractCameraController(dd, parent)
108{
109}
110
111QOrbitCameraController::~QOrbitCameraController()
112{
113}
114
115/*!
116 \property QOrbitCameraController::zoomInLimit
117
118 Holds the current zoom-in limit. The zoom-in limit determines how close to the view center
119 the camera can be zoomed.
120*/
121float QOrbitCameraController::zoomInLimit() const
122{
123 Q_D(const QOrbitCameraController);
124 return d->m_zoomInLimit;
125}
126
127void QOrbitCameraController::setZoomInLimit(float zoomInLimit)
128{
129 Q_D(QOrbitCameraController);
130 if (d->m_zoomInLimit != zoomInLimit) {
131 d->m_zoomInLimit = zoomInLimit;
132 emit zoomInLimitChanged();
133 }
134}
135
136inline float clampInputs(float input1, float input2)
137{
138 float axisValue = input1 + input2;
139 return (axisValue < -1) ? -1 : (axisValue > 1) ? 1 : axisValue;
140}
141
142inline float zoomDistance(QVector3D firstPoint, QVector3D secondPoint)
143{
144 return (secondPoint - firstPoint).lengthSquared();
145}
146
147void QOrbitCameraController::moveCamera(const QAbstractCameraController::InputState &state, float dt)
148{
149 Q_D(QOrbitCameraController);
150
151 Qt3DRender::QCamera *theCamera = camera();
152
153 if (theCamera == nullptr)
154 return;
155
156 const QVector3D upVector(0.0f, 1.0f, 0.0f);
157
158 // Mouse input
159 if (state.leftMouseButtonActive) {
160 if (state.rightMouseButtonActive) {
161 if ( zoomDistance(firstPoint: camera()->position(), secondPoint: theCamera->viewCenter()) > d->m_zoomInLimit * d->m_zoomInLimit) {
162 // Dolly up to limit
163 theCamera->translate(vLocal: QVector3D(0, 0, state.ryAxisValue), option: theCamera->DontTranslateViewCenter);
164 } else {
165 theCamera->translate(vLocal: QVector3D(0, 0, -0.5), option: theCamera->DontTranslateViewCenter);
166 }
167 } else {
168 // Translate
169 theCamera->translate(vLocal: QVector3D(clampInputs(input1: state.rxAxisValue, input2: state.txAxisValue) * linearSpeed(),
170 clampInputs(input1: state.ryAxisValue, input2: state.tyAxisValue) * linearSpeed(),
171 0) * dt);
172 }
173 return;
174 }
175 else if (state.rightMouseButtonActive) {
176 // Orbit
177 theCamera->panAboutViewCenter(angle: (state.rxAxisValue * lookSpeed()) * dt, axis: upVector);
178 theCamera->tiltAboutViewCenter(angle: (state.ryAxisValue * lookSpeed()) * dt);
179 }
180
181 // Keyboard Input
182 if (state.altKeyActive) {
183 // Orbit
184 theCamera->panAboutViewCenter(angle: (state.txAxisValue * lookSpeed()) * dt, axis: upVector);
185 theCamera->tiltAboutViewCenter(angle: (state.tyAxisValue * lookSpeed()) * dt);
186 } else if (state.shiftKeyActive) {
187 if (zoomDistance(firstPoint: camera()->position(), secondPoint: theCamera->viewCenter()) > d->m_zoomInLimit * d->m_zoomInLimit) {
188 // Dolly
189 theCamera->translate(vLocal: QVector3D(0, 0, state.tzAxisValue * linearSpeed() * dt), option: theCamera->DontTranslateViewCenter);
190 } else {
191 theCamera->translate(vLocal: QVector3D(0, 0, -0.5), option: theCamera->DontTranslateViewCenter);
192 }
193 } else {
194 // Translate
195 theCamera->translate(vLocal: QVector3D(clampInputs(input1: state.leftMouseButtonActive ? state.rxAxisValue : 0, input2: state.txAxisValue) * linearSpeed(),
196 clampInputs(input1: state.leftMouseButtonActive ? state.ryAxisValue : 0, input2: state.tyAxisValue) * linearSpeed(),
197 state.tzAxisValue * linearSpeed()) * dt);
198 }
199}
200
201} // Qt3DExtras
202
203QT_END_NAMESPACE
204
205#include "moc_qorbitcameracontroller.cpp"
206

source code of qt3d/src/extras/defaults/qorbitcameracontroller.cpp