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 "qabstractcameracontroller.h"
38#include "qabstractcameracontroller_p.h"
39
40#include <Qt3DRender/QCamera>
41#include <Qt3DInput/QAxis>
42#include <Qt3DInput/QAnalogAxisInput>
43#include <Qt3DInput/QButtonAxisInput>
44#include <Qt3DInput/QAction>
45#include <Qt3DInput/QActionInput>
46#include <Qt3DInput/QLogicalDevice>
47#include <Qt3DInput/QKeyboardDevice>
48#include <Qt3DInput/QMouseDevice>
49#include <Qt3DInput/QMouseEvent>
50#include <Qt3DLogic/QFrameAction>
51#include <QtCore/QtGlobal>
52
53QT_BEGIN_NAMESPACE
54
55namespace Qt3DExtras {
56
57QAbstractCameraControllerPrivate::QAbstractCameraControllerPrivate()
58 : Qt3DCore::QEntityPrivate()
59 , m_camera(nullptr)
60 , m_leftMouseButtonAction(new Qt3DInput::QAction())
61 , m_middleMouseButtonAction(new Qt3DInput::QAction())
62 , m_rightMouseButtonAction(new Qt3DInput::QAction())
63 , m_altButtonAction(new Qt3DInput::QAction())
64 , m_shiftButtonAction(new Qt3DInput::QAction())
65 , m_escapeButtonAction(new Qt3DInput::QAction())
66 , m_rxAxis(new Qt3DInput::QAxis())
67 , m_ryAxis(new Qt3DInput::QAxis())
68 , m_txAxis(new Qt3DInput::QAxis())
69 , m_tyAxis(new Qt3DInput::QAxis())
70 , m_tzAxis(new Qt3DInput::QAxis())
71 , m_leftMouseButtonInput(new Qt3DInput::QActionInput())
72 , m_middleMouseButtonInput(new Qt3DInput::QActionInput())
73 , m_rightMouseButtonInput(new Qt3DInput::QActionInput())
74 , m_altButtonInput(new Qt3DInput::QActionInput())
75 , m_shiftButtonInput(new Qt3DInput::QActionInput())
76 , m_escapeButtonInput(new Qt3DInput::QActionInput())
77 , m_mouseRxInput(new Qt3DInput::QAnalogAxisInput())
78 , m_mouseRyInput(new Qt3DInput::QAnalogAxisInput())
79 , m_mouseTzXInput(new Qt3DInput::QAnalogAxisInput())
80 , m_mouseTzYInput(new Qt3DInput::QAnalogAxisInput())
81 , m_keyboardTxPosInput(new Qt3DInput::QButtonAxisInput())
82 , m_keyboardTyPosInput(new Qt3DInput::QButtonAxisInput())
83 , m_keyboardTzPosInput(new Qt3DInput::QButtonAxisInput())
84 , m_keyboardTxNegInput(new Qt3DInput::QButtonAxisInput())
85 , m_keyboardTyNegInput(new Qt3DInput::QButtonAxisInput())
86 , m_keyboardTzNegInput(new Qt3DInput::QButtonAxisInput())
87 , m_keyboardDevice(new Qt3DInput::QKeyboardDevice())
88 , m_mouseDevice(new Qt3DInput::QMouseDevice())
89 , m_logicalDevice(new Qt3DInput::QLogicalDevice())
90 , m_frameAction(new Qt3DLogic::QFrameAction())
91 , m_linearSpeed(10.0f)
92 , m_lookSpeed(180.0f)
93 , m_acceleration(-1.0f)
94 , m_deceleration(-1.0f)
95 , m_sceneUp(0.0f, 1.0f, 0.0f)
96{}
97
98void QAbstractCameraControllerPrivate::init()
99{
100 //// Actions
101
102 // Left Mouse Button Action
103 m_leftMouseButtonInput->setButtons(QVector<int>() << Qt::LeftButton);
104 m_leftMouseButtonInput->setSourceDevice(m_mouseDevice);
105 m_leftMouseButtonAction->addInput(input: m_leftMouseButtonInput);
106
107 // Middle Mouse Button Action
108 m_middleMouseButtonInput->setButtons(QVector<int>() << Qt::MiddleButton);
109 m_middleMouseButtonInput->setSourceDevice(m_mouseDevice);
110 m_middleMouseButtonAction->addInput(input: m_middleMouseButtonInput);
111
112 // Right Mouse Button Action
113 m_rightMouseButtonInput->setButtons(QVector<int>() << Qt::RightButton);
114 m_rightMouseButtonInput->setSourceDevice(m_mouseDevice);
115 m_rightMouseButtonAction->addInput(input: m_rightMouseButtonInput);
116
117 // Alt Button Action
118 m_altButtonInput->setButtons(QVector<int>() << Qt::Key_Alt);
119 m_altButtonInput->setSourceDevice(m_keyboardDevice);
120 m_altButtonAction->addInput(input: m_altButtonInput);
121
122 // Shift Button Action
123 m_shiftButtonInput->setButtons(QVector<int>() << Qt::Key_Shift);
124 m_shiftButtonInput->setSourceDevice(m_keyboardDevice);
125 m_shiftButtonAction->addInput(input: m_shiftButtonInput);
126
127 // Escape Button Action
128 m_escapeButtonInput->setButtons(QVector<int>() << Qt::Key_Escape);
129 m_escapeButtonInput->setSourceDevice(m_keyboardDevice);
130 m_escapeButtonAction->addInput(input: m_escapeButtonInput);
131
132 //// Axes
133
134 // Mouse X
135 m_mouseRxInput->setAxis(Qt3DInput::QMouseDevice::X);
136 m_mouseRxInput->setSourceDevice(m_mouseDevice);
137 m_rxAxis->addInput(input: m_mouseRxInput);
138
139 // Mouse Y
140 m_mouseRyInput->setAxis(Qt3DInput::QMouseDevice::Y);
141 m_mouseRyInput->setSourceDevice(m_mouseDevice);
142 m_ryAxis->addInput(input: m_mouseRyInput);
143
144 // Mouse Wheel X
145 m_mouseTzXInput->setAxis(Qt3DInput::QMouseDevice::WheelX);
146 m_mouseTzXInput->setSourceDevice(m_mouseDevice);
147 m_tzAxis->addInput(input: m_mouseTzXInput);
148
149 // Mouse Wheel Y
150 m_mouseTzYInput->setAxis(Qt3DInput::QMouseDevice::WheelY);
151 m_mouseTzYInput->setSourceDevice(m_mouseDevice);
152 m_tzAxis->addInput(input: m_mouseTzYInput);
153
154 // Keyboard Pos Tx
155 m_keyboardTxPosInput->setButtons(QVector<int>() << Qt::Key_Right);
156 m_keyboardTxPosInput->setScale(1.0f);
157 m_keyboardTxPosInput->setSourceDevice(m_keyboardDevice);
158 m_txAxis->addInput(input: m_keyboardTxPosInput);
159
160 // Keyboard Pos Tz
161 m_keyboardTzPosInput->setButtons(QVector<int>() << Qt::Key_PageUp);
162 m_keyboardTzPosInput->setScale(1.0f);
163 m_keyboardTzPosInput->setSourceDevice(m_keyboardDevice);
164 m_tzAxis->addInput(input: m_keyboardTzPosInput);
165
166 // Keyboard Pos Ty
167 m_keyboardTyPosInput->setButtons(QVector<int>() << Qt::Key_Up);
168 m_keyboardTyPosInput->setScale(1.0f);
169 m_keyboardTyPosInput->setSourceDevice(m_keyboardDevice);
170 m_tyAxis->addInput(input: m_keyboardTyPosInput);
171
172 // Keyboard Neg Tx
173 m_keyboardTxNegInput->setButtons(QVector<int>() << Qt::Key_Left);
174 m_keyboardTxNegInput->setScale(-1.0f);
175 m_keyboardTxNegInput->setSourceDevice(m_keyboardDevice);
176 m_txAxis->addInput(input: m_keyboardTxNegInput);
177
178 // Keyboard Neg Tz
179 m_keyboardTzNegInput->setButtons(QVector<int>() << Qt::Key_PageDown);
180 m_keyboardTzNegInput->setScale(-1.0f);
181 m_keyboardTzNegInput->setSourceDevice(m_keyboardDevice);
182 m_tzAxis->addInput(input: m_keyboardTzNegInput);
183
184 // Keyboard Neg Ty
185 m_keyboardTyNegInput->setButtons(QVector<int>() << Qt::Key_Down);
186 m_keyboardTyNegInput->setScale(-1.0f);
187 m_keyboardTyNegInput->setSourceDevice(m_keyboardDevice);
188 m_tyAxis->addInput(input: m_keyboardTyNegInput);
189
190 //// Logical Device
191
192 m_logicalDevice->addAction(action: m_leftMouseButtonAction);
193 m_logicalDevice->addAction(action: m_middleMouseButtonAction);
194 m_logicalDevice->addAction(action: m_rightMouseButtonAction);
195 m_logicalDevice->addAction(action: m_altButtonAction);
196 m_logicalDevice->addAction(action: m_shiftButtonAction);
197 m_logicalDevice->addAction(action: m_escapeButtonAction);
198 m_logicalDevice->addAxis(axis: m_rxAxis);
199 m_logicalDevice->addAxis(axis: m_ryAxis);
200 m_logicalDevice->addAxis(axis: m_txAxis);
201 m_logicalDevice->addAxis(axis: m_tyAxis);
202 m_logicalDevice->addAxis(axis: m_tzAxis);
203
204 applyInputAccelerations();
205
206 Q_Q(QAbstractCameraController);
207 //// FrameAction
208
209 // Disable the logical device when the entity is disabled
210 QObject::connect(sender: q, signal: &Qt3DCore::QEntity::enabledChanged,
211 receiver: m_logicalDevice, slot: &Qt3DInput::QLogicalDevice::setEnabled);
212 QObject::connect(sender: q, signal: &Qt3DCore::QEntity::enabledChanged,
213 receiver: m_frameAction, slot: &Qt3DLogic::QFrameAction::setEnabled);
214 for (auto axis: {m_rxAxis, m_ryAxis, m_txAxis, m_tyAxis, m_tzAxis}) {
215 QObject::connect(sender: q, signal: &Qt3DCore::QEntity::enabledChanged,
216 receiver: axis, slot: &Qt3DInput::QAxis::setEnabled);
217 }
218
219 QObject::connect(sender: m_escapeButtonAction, signal: &Qt3DInput::QAction::activeChanged,
220 context: q, slot: [this](bool isActive) {
221 if (isActive && m_camera)
222 m_camera->viewAll();
223 });
224
225 q->addComponent(comp: m_frameAction);
226 q->addComponent(comp: m_logicalDevice);
227}
228
229void QAbstractCameraControllerPrivate::applyInputAccelerations()
230{
231 const auto inputs = {
232 m_keyboardTxPosInput,
233 m_keyboardTyPosInput,
234 m_keyboardTzPosInput,
235 m_keyboardTxNegInput,
236 m_keyboardTyNegInput,
237 m_keyboardTzNegInput
238 };
239
240 for (auto input : inputs) {
241 input->setAcceleration(m_acceleration);
242 input->setDeceleration(m_deceleration);
243 }
244}
245
246/*!
247 \class Qt3DExtras::QAbstractCameraController
248
249 \brief The QAbstractCameraController class provides basic
250 functionality for camera controllers.
251
252 \inmodule Qt3DExtras
253 \since 5.10
254
255 QAbstractCameraController sets up and handles input from keyboard,
256 mouse, and other devices. QAbstractCameraController is an abstract
257 class and cannot itself be instantiated. It provides a standard
258 interface for camera controllers.
259
260 Derived classes need only implement the frameActionTriggered()
261 method to move the camera.
262*/
263
264/*!
265 \fn void Qt3DExtras::QAbstractCameraController::moveCamera(const InputState &state, float dt) = 0
266
267 This method is called whenever a frame action is triggered. Derived
268 classes must override this method to implement the camera movement
269 specific to the controller.
270
271 In the base class this is a pure virtual function.
272*/
273
274QAbstractCameraController::QAbstractCameraController(Qt3DCore::QNode *parent)
275 : QAbstractCameraController(*new QAbstractCameraControllerPrivate, parent)
276{
277}
278
279/*! \internal
280 */
281QAbstractCameraController::QAbstractCameraController(QAbstractCameraControllerPrivate &dd, Qt3DCore::QNode *parent)
282 : Qt3DCore::QEntity(dd, parent)
283{
284 Q_D(QAbstractCameraController);
285 d->init();
286
287 QObject::connect(sender: d->m_frameAction, signal: &Qt3DLogic::QFrameAction::triggered,
288 context: this, slot: [=] (float dt) {
289 InputState state;
290
291 state.rxAxisValue = d->m_rxAxis->value();
292 state.ryAxisValue = d->m_ryAxis->value();
293 state.txAxisValue = d->m_txAxis->value();
294 state.tyAxisValue = d->m_tyAxis->value();
295 state.tzAxisValue = d->m_tzAxis->value();
296
297 state.leftMouseButtonActive = d->m_leftMouseButtonAction->isActive();
298 state.middleMouseButtonActive = d->m_middleMouseButtonAction->isActive();
299 state.rightMouseButtonActive = d->m_rightMouseButtonAction->isActive();
300
301 state.altKeyActive = d->m_altButtonAction->isActive();
302 state.shiftKeyActive = d->m_shiftButtonAction->isActive();
303
304 moveCamera(state, dt);
305 });
306}
307
308QAbstractCameraController::~QAbstractCameraController()
309{
310}
311
312/*!
313 \property Qt3DExtras::QAbstractCameraController::camera
314
315 Holds the currently controlled camera.
316*/
317Qt3DRender::QCamera *QAbstractCameraController::camera() const
318{
319 Q_D(const QAbstractCameraController);
320 return d->m_camera;
321}
322
323/*!
324 \property Qt3DExtras::QAbstractCameraController::linearSpeed
325
326 Holds the current linear speed of the camera controller. Linear speed determines the
327 movement speed of the camera.
328
329 The default is \c {10.0}.
330*/
331float QAbstractCameraController::linearSpeed() const
332{
333 Q_D(const QAbstractCameraController);
334 return d->m_linearSpeed;
335}
336
337/*!
338 \property Qt3DExtras::QAbstractCameraController::lookSpeed
339
340 Holds the current look speed of the camera controller. The look speed determines the turn rate
341 of the camera pan and tilt.
342
343 The default is \c {180.0}.
344*/
345float QAbstractCameraController::lookSpeed() const
346{
347 Q_D(const QAbstractCameraController);
348 return d->m_lookSpeed;
349}
350
351/*!
352 \property Qt3DExtras::QAbstractCameraController::acceleration
353
354 Holds the current acceleration of the camera controller.
355*/
356float QAbstractCameraController::acceleration() const
357{
358 Q_D(const QAbstractCameraController);
359 return d->m_acceleration;
360}
361
362/*!
363 \property Qt3DExtras::QAbstractCameraController::deceleration
364
365 Holds the current deceleration of the camera controller.
366*/
367float QAbstractCameraController::deceleration() const
368{
369 Q_D(const QAbstractCameraController);
370 return d->m_deceleration;
371}
372
373void QAbstractCameraController::setCamera(Qt3DRender::QCamera *camera)
374{
375 Q_D(QAbstractCameraController);
376 if (d->m_camera != camera) {
377
378 if (d->m_camera)
379 d->unregisterDestructionHelper(node: d->m_camera);
380
381 if (camera && !camera->parent())
382 camera->setParent(this);
383
384 d->m_camera = camera;
385
386 // Ensures proper bookkeeping
387 if (d->m_camera)
388 d->registerDestructionHelper(node: d->m_camera, func: &QAbstractCameraController::setCamera, d->m_camera);
389
390 emit cameraChanged();
391 }
392}
393
394void QAbstractCameraController::setLinearSpeed(float linearSpeed)
395{
396 Q_D(QAbstractCameraController);
397 if (d->m_linearSpeed != linearSpeed) {
398 d->m_linearSpeed = linearSpeed;
399 emit linearSpeedChanged();
400 }
401}
402
403void QAbstractCameraController::setLookSpeed(float lookSpeed)
404{
405 Q_D(QAbstractCameraController);
406 if (d->m_lookSpeed != lookSpeed) {
407 d->m_lookSpeed = lookSpeed;
408 emit lookSpeedChanged();
409 }
410}
411
412void QAbstractCameraController::setAcceleration(float acceleration)
413{
414 Q_D(QAbstractCameraController);
415 if (d->m_acceleration != acceleration) {
416 d->m_acceleration = acceleration;
417 d->applyInputAccelerations();
418 emit accelerationChanged(acceleration);
419 }
420}
421
422void QAbstractCameraController::setDeceleration(float deceleration)
423{
424 Q_D(QAbstractCameraController);
425 if (d->m_deceleration != deceleration) {
426 d->m_deceleration = deceleration;
427 d->applyInputAccelerations();
428 emit decelerationChanged(deceleration);
429 }
430}
431
432/*!
433 Provides access to the keyboard device.
434*/
435
436Qt3DInput::QKeyboardDevice *QAbstractCameraController::keyboardDevice() const
437{
438 Q_D(const QAbstractCameraController);
439 return d->m_keyboardDevice;
440}
441
442/*!
443 Provides access to the mouse device.
444*/
445
446Qt3DInput::QMouseDevice *QAbstractCameraController::mouseDevice() const
447{
448 Q_D(const QAbstractCameraController);
449 return d->m_mouseDevice;
450}
451
452} // Qt3DExtras
453
454QT_END_NAMESPACE
455
456#include "moc_qabstractcameracontroller.cpp"
457

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