1// Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qorbitcameracontroller.h"
5#include "qorbitcameracontroller_p.h"
6
7#include <Qt3DRender/QCamera>
8
9QT_BEGIN_NAMESPACE
10
11namespace Qt3DExtras {
12
13QOrbitCameraControllerPrivate::QOrbitCameraControllerPrivate()
14 : m_zoomInLimit(2.0f)
15{}
16
17/*!
18 \class Qt3DExtras::QOrbitCameraController
19 \ingroup qt3d-extras-cameracontrollers
20 \brief The QOrbitCameraController class allows controlling the scene camera along orbital path.
21 \inmodule Qt3DExtras
22 \since 5.7
23 \inherits Qt3DCore::QEntity
24
25 The controls are:
26 \table
27 \header
28 \li Input
29 \li Action
30 \row
31 \li Left mouse button
32 \li While the left mouse button is pressed, mouse movement along x-axis moves the camera
33 left and right and movement along y-axis moves it up and down.
34 \row
35 \li Right mouse button
36 \li While the right mouse button is pressed, mouse movement along x-axis pans the camera
37 around the camera view center and movement along y-axis tilts it around the camera
38 view center.
39 \row
40 \li Both left and right mouse button
41 \li While both the left and the right mouse button are pressed, mouse movement along y-axis
42 zooms the camera in and out without changing the view center.
43 \row
44 \li Mouse scroll wheel
45 \li Zooms the camera in and out without changing the view center.
46 \row
47 \li Arrow keys
48 \li Move the camera vertically and horizontally relative to camera viewport.
49 \row
50 \li Page up and page down keys
51 \li Move the camera forwards and backwards.
52 \row
53 \li Shift key
54 \li Changes the behavior of the up and down arrow keys to zoom the camera in and out
55 without changing the view center. The other movement keys are disabled.
56 \row
57 \li Alt key
58 \li Changes the behovior of the arrow keys to pan and tilt the camera around the view
59 center. Disables the page up and page down keys.
60 \row
61 \li Escape
62 \li Moves the camera so that entire scene is visible in the camera viewport.
63 \endtable
64*/
65
66QOrbitCameraController::QOrbitCameraController(Qt3DCore::QNode *parent)
67 : QOrbitCameraController(*new QOrbitCameraControllerPrivate, parent)
68{
69}
70
71/*! \internal
72 */
73QOrbitCameraController::QOrbitCameraController(QOrbitCameraControllerPrivate &dd, Qt3DCore::QNode *parent)
74 : QAbstractCameraController(dd, parent)
75{
76}
77
78QOrbitCameraController::~QOrbitCameraController()
79{
80}
81
82/*!
83 \property QOrbitCameraController::zoomInLimit
84
85 Holds the current zoom-in limit. The zoom-in limit determines how close to the view center
86 the camera can be zoomed.
87*/
88float QOrbitCameraController::zoomInLimit() const
89{
90 Q_D(const QOrbitCameraController);
91 return d->m_zoomInLimit;
92}
93
94void QOrbitCameraController::setZoomInLimit(float zoomInLimit)
95{
96 Q_D(QOrbitCameraController);
97 if (d->m_zoomInLimit != zoomInLimit) {
98 d->m_zoomInLimit = zoomInLimit;
99 emit zoomInLimitChanged();
100 }
101}
102
103inline float clampInputs(float input1, float input2)
104{
105 float axisValue = input1 + input2;
106 return (axisValue < -1) ? -1 : (axisValue > 1) ? 1 : axisValue;
107}
108
109inline float zoomDistance(QVector3D firstPoint, QVector3D secondPoint)
110{
111 return (secondPoint - firstPoint).lengthSquared();
112}
113
114void QOrbitCameraController::moveCamera(const QAbstractCameraController::InputState &state, float dt)
115{
116 Q_D(QOrbitCameraController);
117
118 Qt3DRender::QCamera *theCamera = camera();
119
120 if (theCamera == nullptr)
121 return;
122
123 const QVector3D upVector(0.0f, 1.0f, 0.0f);
124
125 // Mouse input
126 if (state.leftMouseButtonActive) {
127 if (state.rightMouseButtonActive) {
128 if ( zoomDistance(firstPoint: camera()->position(), secondPoint: theCamera->viewCenter()) > d->m_zoomInLimit * d->m_zoomInLimit) {
129 // Dolly up to limit
130 theCamera->translate(vLocal: QVector3D(0, 0, state.ryAxisValue), option: theCamera->DontTranslateViewCenter);
131 } else {
132 theCamera->translate(vLocal: QVector3D(0, 0, -0.5), option: theCamera->DontTranslateViewCenter);
133 }
134 } else {
135 // Translate
136 theCamera->translate(vLocal: QVector3D(clampInputs(input1: state.rxAxisValue, input2: state.txAxisValue) * linearSpeed(),
137 clampInputs(input1: state.ryAxisValue, input2: state.tyAxisValue) * linearSpeed(),
138 0) * dt);
139 }
140 return;
141 }
142 else if (state.rightMouseButtonActive) {
143 // Orbit
144 theCamera->panAboutViewCenter(angle: (state.rxAxisValue * lookSpeed()) * dt, axis: upVector);
145 theCamera->tiltAboutViewCenter(angle: (state.ryAxisValue * lookSpeed()) * dt);
146 }
147
148 // Keyboard Input
149 if (state.altKeyActive) {
150 // Orbit
151 theCamera->panAboutViewCenter(angle: (state.txAxisValue * lookSpeed()) * dt, axis: upVector);
152 theCamera->tiltAboutViewCenter(angle: (state.tyAxisValue * lookSpeed()) * dt);
153 } else if (state.shiftKeyActive) {
154 if (zoomDistance(firstPoint: camera()->position(), secondPoint: theCamera->viewCenter()) > d->m_zoomInLimit * d->m_zoomInLimit) {
155 // Dolly
156 theCamera->translate(vLocal: QVector3D(0, 0, state.tzAxisValue * linearSpeed() * dt), option: theCamera->DontTranslateViewCenter);
157 } else {
158 theCamera->translate(vLocal: QVector3D(0, 0, -0.5), option: theCamera->DontTranslateViewCenter);
159 }
160 } else {
161 // Translate
162 theCamera->translate(vLocal: QVector3D(clampInputs(input1: state.leftMouseButtonActive ? state.rxAxisValue : 0, input2: state.txAxisValue) * linearSpeed(),
163 clampInputs(input1: state.leftMouseButtonActive ? state.ryAxisValue : 0, input2: state.tyAxisValue) * linearSpeed(),
164 state.tzAxisValue * linearSpeed()) * dt);
165 }
166}
167
168} // Qt3DExtras
169
170QT_END_NAMESPACE
171
172#include "moc_qorbitcameracontroller.cpp"
173

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