From d4fb24c0871320667640f100b743f34f702db6cf Mon Sep 17 00:00:00 2001 From: Andy Maloney Date: Tue, 29 Aug 2017 00:05:05 -0400 Subject: Add Qt3DExtras::QAbstractCameraController Abstracted the orbit and first person camera controllers into a base class. These two controllers shared a lot of similarities. This allows developers to easily create a custom camera controller by deriving from QAbstractCameraController and implementing one function. [ChangeLog][Qt3DExtras][] Added Qt3DExtras::QAbstractCameraController abstract base class to make implementing new camera controllers easier. Change-Id: I43cfbc03f7294b1740f199ac7ededa9578234974 Reviewed-by: Paul Lemire --- src/extras/defaults/defaults.pri | 3 + src/extras/defaults/qabstractcameracontroller.cpp | 436 +++++++++++++++++++++ src/extras/defaults/qabstractcameracontroller.h | 126 ++++++ src/extras/defaults/qabstractcameracontroller_p.h | 141 +++++++ .../defaults/qfirstpersoncameracontroller.cpp | 305 +------------- src/extras/defaults/qfirstpersoncameracontroller.h | 39 +- .../defaults/qfirstpersoncameracontroller_p.h | 152 ------- src/extras/defaults/qorbitcameracontroller.cpp | 348 ++++------------ src/extras/defaults/qorbitcameracontroller.h | 28 +- src/extras/defaults/qorbitcameracontroller_p.h | 75 +--- 10 files changed, 810 insertions(+), 843 deletions(-) create mode 100644 src/extras/defaults/qabstractcameracontroller.cpp create mode 100644 src/extras/defaults/qabstractcameracontroller.h create mode 100644 src/extras/defaults/qabstractcameracontroller_p.h delete mode 100644 src/extras/defaults/qfirstpersoncameracontroller_p.h diff --git a/src/extras/defaults/defaults.pri b/src/extras/defaults/defaults.pri index d3fd122ae..2575de1a3 100644 --- a/src/extras/defaults/defaults.pri +++ b/src/extras/defaults/defaults.pri @@ -25,6 +25,8 @@ HEADERS += \ $$PWD/qphongalphamaterial_p.h \ $$PWD/qt3dwindow.h \ $$PWD/qt3dwindow_p.h \ + $$PWD/qabstractcameracontroller.h \ + $$PWD/qabstractcameracontroller_p.h \ $$PWD/qfirstpersoncameracontroller.h \ $$PWD/qfirstpersoncameracontroller_p.h \ $$PWD/qorbitcameracontroller.h \ @@ -58,6 +60,7 @@ SOURCES += \ $$PWD/qgoochmaterial.cpp \ $$PWD/qphongalphamaterial.cpp \ $$PWD/qt3dwindow.cpp \ + $$PWD/qabstractcameracontroller.cpp \ $$PWD/qfirstpersoncameracontroller.cpp \ $$PWD/qorbitcameracontroller.cpp \ $$PWD/qabstractspritesheet.cpp \ diff --git a/src/extras/defaults/qabstractcameracontroller.cpp b/src/extras/defaults/qabstractcameracontroller.cpp new file mode 100644 index 000000000..8bf57f5fa --- /dev/null +++ b/src/extras/defaults/qabstractcameracontroller.cpp @@ -0,0 +1,436 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qabstractcameracontroller.h" +#include "qabstractcameracontroller_p.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +QAbstractCameraControllerPrivate::QAbstractCameraControllerPrivate() + : Qt3DCore::QEntityPrivate() + , m_camera(nullptr) + , m_leftMouseButtonAction(new Qt3DInput::QAction()) + , m_middleMouseButtonAction(new Qt3DInput::QAction()) + , m_rightMouseButtonAction(new Qt3DInput::QAction()) + , m_altButtonAction(new Qt3DInput::QAction()) + , m_shiftButtonAction(new Qt3DInput::QAction()) + , m_rxAxis(new Qt3DInput::QAxis()) + , m_ryAxis(new Qt3DInput::QAxis()) + , m_txAxis(new Qt3DInput::QAxis()) + , m_tyAxis(new Qt3DInput::QAxis()) + , m_tzAxis(new Qt3DInput::QAxis()) + , m_leftMouseButtonInput(new Qt3DInput::QActionInput()) + , m_middleMouseButtonInput(new Qt3DInput::QActionInput()) + , m_rightMouseButtonInput(new Qt3DInput::QActionInput()) + , m_altButtonInput(new Qt3DInput::QActionInput()) + , m_shiftButtonInput(new Qt3DInput::QActionInput()) + , m_mouseRxInput(new Qt3DInput::QAnalogAxisInput()) + , m_mouseRyInput(new Qt3DInput::QAnalogAxisInput()) + , m_mouseTzXInput(new Qt3DInput::QAnalogAxisInput()) + , m_mouseTzYInput(new Qt3DInput::QAnalogAxisInput()) + , m_keyboardTxPosInput(new Qt3DInput::QButtonAxisInput()) + , m_keyboardTyPosInput(new Qt3DInput::QButtonAxisInput()) + , m_keyboardTzPosInput(new Qt3DInput::QButtonAxisInput()) + , m_keyboardTxNegInput(new Qt3DInput::QButtonAxisInput()) + , m_keyboardTyNegInput(new Qt3DInput::QButtonAxisInput()) + , m_keyboardTzNegInput(new Qt3DInput::QButtonAxisInput()) + , m_keyboardDevice(new Qt3DInput::QKeyboardDevice()) + , m_mouseDevice(new Qt3DInput::QMouseDevice()) + , m_logicalDevice(new Qt3DInput::QLogicalDevice()) + , m_frameAction(new Qt3DLogic::QFrameAction()) + , m_linearSpeed(10.0f) + , m_lookSpeed(180.0f) + , m_acceleration(-1.0f) + , m_deceleration(-1.0f) + , m_sceneUp(0.0f, 1.0f, 0.0f) +{} + +void QAbstractCameraControllerPrivate::init() +{ + //// Actions + + // Left Mouse Button Action + m_leftMouseButtonInput->setButtons(QVector() << Qt::LeftButton); + m_leftMouseButtonInput->setSourceDevice(m_mouseDevice); + m_leftMouseButtonAction->addInput(m_leftMouseButtonInput); + + // Middle Mouse Button Action + m_middleMouseButtonInput->setButtons(QVector() << Qt::MiddleButton); + m_middleMouseButtonInput->setSourceDevice(m_mouseDevice); + m_middleMouseButtonAction->addInput(m_middleMouseButtonInput); + + // Right Mouse Button Action + m_rightMouseButtonInput->setButtons(QVector() << Qt::RightButton); + m_rightMouseButtonInput->setSourceDevice(m_mouseDevice); + m_rightMouseButtonAction->addInput(m_rightMouseButtonInput); + + // Alt Button Action + m_altButtonInput->setButtons(QVector() << Qt::Key_Alt); + m_altButtonInput->setSourceDevice(m_keyboardDevice); + m_altButtonAction->addInput(m_altButtonInput); + + // Shift Button Action + m_shiftButtonInput->setButtons(QVector() << Qt::Key_Shift); + m_shiftButtonInput->setSourceDevice(m_keyboardDevice); + m_shiftButtonAction->addInput(m_shiftButtonInput); + + //// Axes + + // Mouse X + m_mouseRxInput->setAxis(Qt3DInput::QMouseDevice::X); + m_mouseRxInput->setSourceDevice(m_mouseDevice); + m_rxAxis->addInput(m_mouseRxInput); + + // Mouse Y + m_mouseRyInput->setAxis(Qt3DInput::QMouseDevice::Y); + m_mouseRyInput->setSourceDevice(m_mouseDevice); + m_ryAxis->addInput(m_mouseRyInput); + + // Mouse Wheel X + m_mouseTzXInput->setAxis(Qt3DInput::QMouseDevice::WheelX); + m_mouseTzXInput->setSourceDevice(m_mouseDevice); + m_tzAxis->addInput(m_mouseTzXInput); + + // Mouse Wheel Y + m_mouseTzYInput->setAxis(Qt3DInput::QMouseDevice::WheelY); + m_mouseTzYInput->setSourceDevice(m_mouseDevice); + m_tzAxis->addInput(m_mouseTzYInput); + + // Keyboard Pos Tx + m_keyboardTxPosInput->setButtons(QVector() << Qt::Key_Right); + m_keyboardTxPosInput->setScale(1.0f); + m_keyboardTxPosInput->setSourceDevice(m_keyboardDevice); + m_txAxis->addInput(m_keyboardTxPosInput); + + // Keyboard Pos Tz + m_keyboardTzPosInput->setButtons(QVector() << Qt::Key_PageUp); + m_keyboardTzPosInput->setScale(1.0f); + m_keyboardTzPosInput->setSourceDevice(m_keyboardDevice); + m_tzAxis->addInput(m_keyboardTzPosInput); + + // Keyboard Pos Ty + m_keyboardTyPosInput->setButtons(QVector() << Qt::Key_Up); + m_keyboardTyPosInput->setScale(1.0f); + m_keyboardTyPosInput->setSourceDevice(m_keyboardDevice); + m_tyAxis->addInput(m_keyboardTyPosInput); + + // Keyboard Neg Tx + m_keyboardTxNegInput->setButtons(QVector() << Qt::Key_Left); + m_keyboardTxNegInput->setScale(-1.0f); + m_keyboardTxNegInput->setSourceDevice(m_keyboardDevice); + m_txAxis->addInput(m_keyboardTxNegInput); + + // Keyboard Neg Tz + m_keyboardTzNegInput->setButtons(QVector() << Qt::Key_PageDown); + m_keyboardTzNegInput->setScale(-1.0f); + m_keyboardTzNegInput->setSourceDevice(m_keyboardDevice); + m_tzAxis->addInput(m_keyboardTzNegInput); + + // Keyboard Neg Ty + m_keyboardTyNegInput->setButtons(QVector() << Qt::Key_Down); + m_keyboardTyNegInput->setScale(-1.0f); + m_keyboardTyNegInput->setSourceDevice(m_keyboardDevice); + m_tyAxis->addInput(m_keyboardTyNegInput); + + //// Logical Device + + m_logicalDevice->addAction(m_leftMouseButtonAction); + m_logicalDevice->addAction(m_middleMouseButtonAction); + m_logicalDevice->addAction(m_rightMouseButtonAction); + m_logicalDevice->addAction(m_altButtonAction); + m_logicalDevice->addAction(m_shiftButtonAction); + m_logicalDevice->addAxis(m_rxAxis); + m_logicalDevice->addAxis(m_ryAxis); + m_logicalDevice->addAxis(m_txAxis); + m_logicalDevice->addAxis(m_tyAxis); + m_logicalDevice->addAxis(m_tzAxis); + + applyInputAccelerations(); + + Q_Q(QAbstractCameraController); + //// FrameAction + + // Disable the logical device when the entity is disabled + QObject::connect(q, &Qt3DCore::QEntity::enabledChanged, + m_logicalDevice, &Qt3DInput::QLogicalDevice::setEnabled); + + q->addComponent(m_frameAction); + q->addComponent(m_logicalDevice); +} + +void QAbstractCameraControllerPrivate::applyInputAccelerations() +{ + const auto inputs = { + m_keyboardTxPosInput, + m_keyboardTyPosInput, + m_keyboardTzPosInput, + m_keyboardTxNegInput, + m_keyboardTyNegInput, + m_keyboardTzNegInput + }; + + for (auto input : inputs) { + input->setAcceleration(m_acceleration); + input->setDeceleration(m_deceleration); + } +} + +/*! + \class QAbstractCameraController + + \brief The QAbstractCameraController class provides basic + functionality for camera controllers. + + \inmodule Qt3DExtras + \since 5.10 + + QAbstractCameraController sets up and handles input from keyboard, + mouse, and other devices. QAbstractCameraController is an abstract + class and cannot itself be instantiated. It provides a standard + interface for camera controllers. + + Derived classes need only implement the frameActionTriggered() + method to move the camera. +*/ + +/*! + \fn void QAbstractCameraController::moveCamera(const InputState &state, float dt) = 0 + + This method is called whenever a frame action is triggered. Derived + classes must override this method to implement the camera movement + specific to the controller. + + In the base class this is a pure virtual function. +*/ + +QAbstractCameraController::QAbstractCameraController(Qt3DCore::QNode *parent) + : QAbstractCameraController(*new QAbstractCameraControllerPrivate, parent) +{ +} + +/*! \internal + */ +QAbstractCameraController::QAbstractCameraController(QAbstractCameraControllerPrivate &dd, Qt3DCore::QNode *parent) + : Qt3DCore::QEntity(dd, parent) +{ + Q_D(QAbstractCameraController); + d->init(); + + QObject::connect(d->m_frameAction, &Qt3DLogic::QFrameAction::triggered, + this, [=] (float dt) { + InputState state; + + state.rxAxisValue = d->m_rxAxis->value(); + state.ryAxisValue = d->m_ryAxis->value(); + state.txAxisValue = d->m_txAxis->value(); + state.tyAxisValue = d->m_tyAxis->value(); + state.tzAxisValue = d->m_tzAxis->value(); + + state.leftMouseButtonActive = d->m_leftMouseButtonAction->isActive(); + state.middleMouseButtonActive = d->m_middleMouseButtonAction->isActive(); + state.rightMouseButtonActive = d->m_rightMouseButtonAction->isActive(); + + state.altKeyActive = d->m_altButtonAction->isActive(); + state.shiftKeyActive = d->m_shiftButtonAction->isActive(); + + moveCamera(state, dt); + }); +} + +QAbstractCameraController::~QAbstractCameraController() +{ +} + +/*! + \property QAbstractCameraController::camera + + Holds the currently controlled camera. +*/ +Qt3DRender::QCamera *QAbstractCameraController::camera() const +{ + Q_D(const QAbstractCameraController); + return d->m_camera; +} + +/*! + \property QAbstractCameraController::linearSpeed + + Holds the current linear speed of the camera controller. Linear speed determines the + movement speed of the camera. + + The default is 10.0. +*/ +float QAbstractCameraController::linearSpeed() const +{ + Q_D(const QAbstractCameraController); + return d->m_linearSpeed; +} + +/*! + \property QAbstractCameraController::lookSpeed + + Holds the current look speed of the camera controller. The look speed determines the turn rate + of the camera pan and tilt. + + The default is 180.0. +*/ +float QAbstractCameraController::lookSpeed() const +{ + Q_D(const QAbstractCameraController); + return d->m_lookSpeed; +} + +/*! + \property QAbstractCameraController::acceleration + + Holds the current acceleration of the camera controller. +*/ +float QAbstractCameraController::acceleration() const +{ + Q_D(const QAbstractCameraController); + return d->m_acceleration; +} + +/*! + \property QAbstractCameraController::deceleration + + Holds the current deceleration of the camera controller. +*/ +float QAbstractCameraController::deceleration() const +{ + Q_D(const QAbstractCameraController); + return d->m_deceleration; +} + +void QAbstractCameraController::setCamera(Qt3DRender::QCamera *camera) +{ + Q_D(QAbstractCameraController); + if (d->m_camera != camera) { + + if (d->m_camera) + d->unregisterDestructionHelper(d->m_camera); + + if (camera && !camera->parent()) + camera->setParent(this); + + d->m_camera = camera; + + // Ensures proper bookkeeping + if (d->m_camera) + d->registerDestructionHelper(d->m_camera, &QAbstractCameraController::setCamera, d->m_camera); + + emit cameraChanged(); + } +} + +void QAbstractCameraController::setLinearSpeed(float linearSpeed) +{ + Q_D(QAbstractCameraController); + if (d->m_linearSpeed != linearSpeed) { + d->m_linearSpeed = linearSpeed; + emit linearSpeedChanged(); + } +} + +void QAbstractCameraController::setLookSpeed(float lookSpeed) +{ + Q_D(QAbstractCameraController); + if (d->m_lookSpeed != lookSpeed) { + d->m_lookSpeed = lookSpeed; + emit lookSpeedChanged(); + } +} + +void QAbstractCameraController::setAcceleration(float acceleration) +{ + Q_D(QAbstractCameraController); + if (d->m_acceleration != acceleration) { + d->m_acceleration = acceleration; + d->applyInputAccelerations(); + emit accelerationChanged(acceleration); + } +} + +void QAbstractCameraController::setDeceleration(float deceleration) +{ + Q_D(QAbstractCameraController); + if (d->m_deceleration != deceleration) { + d->m_deceleration = deceleration; + d->applyInputAccelerations(); + emit decelerationChanged(deceleration); + } +} + +/*! + Provides access to the keyboard device. +*/ + +Qt3DInput::QKeyboardDevice *QAbstractCameraController::keyboardDevice() const +{ + Q_D(const QAbstractCameraController); + return d->m_keyboardDevice; +} + +/*! + Provides access to the mouse device. +*/ + +Qt3DInput::QMouseDevice *QAbstractCameraController::mouseDevice() const +{ + Q_D(const QAbstractCameraController); + return d->m_mouseDevice; +} + +} // Qt3DExtras + +QT_END_NAMESPACE + +#include "moc_qabstractcameracontroller.cpp" diff --git a/src/extras/defaults/qabstractcameracontroller.h b/src/extras/defaults/qabstractcameracontroller.h new file mode 100644 index 000000000..f13079f5f --- /dev/null +++ b/src/extras/defaults/qabstractcameracontroller.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QABSTRACTCAMERACONTROLLER_H +#define QT3DEXTRAS_QABSTRACTCAMERACONTROLLER_H + +#include +#include + +QT_BEGIN_NAMESPACE + +namespace Qt3DInput { +class QKeyboardDevice; +class QMouseDevice; +} + +namespace Qt3DRender { +class QCamera; +} + +namespace Qt3DExtras { + +class QAbstractCameraControllerPrivate; + +class QT3DEXTRASSHARED_EXPORT QAbstractCameraController : public Qt3DCore::QEntity +{ + Q_OBJECT + Q_PROPERTY(Qt3DRender::QCamera *camera READ camera WRITE setCamera NOTIFY cameraChanged) + Q_PROPERTY(float linearSpeed READ linearSpeed WRITE setLinearSpeed NOTIFY linearSpeedChanged) + Q_PROPERTY(float lookSpeed READ lookSpeed WRITE setLookSpeed NOTIFY lookSpeedChanged) + Q_PROPERTY(float acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged) + Q_PROPERTY(float deceleration READ deceleration WRITE setDeceleration NOTIFY decelerationChanged) + +public: + ~QAbstractCameraController(); + + Qt3DRender::QCamera *camera() const; + float linearSpeed() const; + float lookSpeed() const; + + float acceleration() const; + float deceleration() const; + + void setCamera(Qt3DRender::QCamera *camera); + void setLinearSpeed(float linearSpeed); + void setLookSpeed(float lookSpeed); + + void setAcceleration(float acceleration); + void setDeceleration(float deceleration); + +Q_SIGNALS: + void cameraChanged(); + void linearSpeedChanged(); + void lookSpeedChanged(); + + void accelerationChanged(float acceleration); + void decelerationChanged(float deceleration); + +protected: + explicit QAbstractCameraController(Qt3DCore::QNode *parent = nullptr); + QAbstractCameraController(QAbstractCameraControllerPrivate &dd, Qt3DCore::QNode *parent = nullptr); + + Qt3DInput::QKeyboardDevice *keyboardDevice() const; + Qt3DInput::QMouseDevice *mouseDevice() const; + + struct InputState + { + float rxAxisValue; + float ryAxisValue; + float txAxisValue; + float tyAxisValue; + float tzAxisValue; + + bool leftMouseButtonActive; + bool middleMouseButtonActive; + bool rightMouseButtonActive; + + bool altKeyActive; + bool shiftKeyActive; + }; + +private: + virtual void moveCamera(const InputState &state, float dt) = 0; + +private: + Q_DECLARE_PRIVATE(QAbstractCameraController) +}; + +} // Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QABSTRACTCAMERACONTROLLER_H diff --git a/src/extras/defaults/qabstractcameracontroller_p.h b/src/extras/defaults/qabstractcameracontroller_p.h new file mode 100644 index 000000000..00424a55b --- /dev/null +++ b/src/extras/defaults/qabstractcameracontroller_p.h @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QABSTRACTCAMERACONTROLLER_P_H +#define QT3DEXTRAS_QABSTRACTCAMERACONTROLLER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { +class QCamera; +} + +namespace Qt3DLogic { +class QFrameAction; +} + +namespace Qt3DInput { +class QKeyboardDevice; +class QMouseDevice; +class QLogicalDevice; +class QAction; +class QActionInput; +class QAxis; +class QAnalogAxisInput; +class QButtonAxisInput; +class QAxisActionHandler; +} + +namespace Qt3DExtras { + +class QAbstractCameraControllerPrivate : public Qt3DCore::QEntityPrivate +{ +public: + QAbstractCameraControllerPrivate(); + + void init(); + void applyInputAccelerations(); + + Qt3DRender::QCamera *m_camera; + + Qt3DInput::QAction *m_leftMouseButtonAction; + Qt3DInput::QAction *m_middleMouseButtonAction; + Qt3DInput::QAction *m_rightMouseButtonAction; + Qt3DInput::QAction *m_altButtonAction; + Qt3DInput::QAction *m_shiftButtonAction; + + Qt3DInput::QAxis *m_rxAxis; + Qt3DInput::QAxis *m_ryAxis; + Qt3DInput::QAxis *m_txAxis; + Qt3DInput::QAxis *m_tyAxis; + Qt3DInput::QAxis *m_tzAxis; + + Qt3DInput::QActionInput *m_leftMouseButtonInput; + Qt3DInput::QActionInput *m_middleMouseButtonInput; + Qt3DInput::QActionInput *m_rightMouseButtonInput; + Qt3DInput::QActionInput *m_altButtonInput; + Qt3DInput::QActionInput *m_shiftButtonInput; + + Qt3DInput::QAnalogAxisInput *m_mouseRxInput; + Qt3DInput::QAnalogAxisInput *m_mouseRyInput; + Qt3DInput::QAnalogAxisInput *m_mouseTzXInput; + Qt3DInput::QAnalogAxisInput *m_mouseTzYInput; + Qt3DInput::QButtonAxisInput *m_keyboardTxPosInput; + Qt3DInput::QButtonAxisInput *m_keyboardTyPosInput; + Qt3DInput::QButtonAxisInput *m_keyboardTzPosInput; + Qt3DInput::QButtonAxisInput *m_keyboardTxNegInput; + Qt3DInput::QButtonAxisInput *m_keyboardTyNegInput; + Qt3DInput::QButtonAxisInput *m_keyboardTzNegInput; + + Qt3DInput::QKeyboardDevice *m_keyboardDevice; + Qt3DInput::QMouseDevice *m_mouseDevice; + + Qt3DInput::QLogicalDevice *m_logicalDevice; + + Qt3DLogic::QFrameAction *m_frameAction; + + float m_linearSpeed; + float m_lookSpeed; + + float m_acceleration; + float m_deceleration; + + QVector3D m_sceneUp; + + Q_DECLARE_PUBLIC(QAbstractCameraController) +}; + +} // namespace Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QABSTRACTCAMERACONTROLLER_P_H diff --git a/src/extras/defaults/qfirstpersoncameracontroller.cpp b/src/extras/defaults/qfirstpersoncameracontroller.cpp index 5321bfcf2..2ad997d05 100644 --- a/src/extras/defaults/qfirstpersoncameracontroller.cpp +++ b/src/extras/defaults/qfirstpersoncameracontroller.cpp @@ -35,188 +35,13 @@ ****************************************************************************/ #include "qfirstpersoncameracontroller.h" -#include "qfirstpersoncameracontroller_p.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include QT_BEGIN_NAMESPACE namespace Qt3DExtras { -QFirstPersonCameraControllerPrivate::QFirstPersonCameraControllerPrivate() - : Qt3DCore::QEntityPrivate() - , m_camera(nullptr) - , m_leftMouseButtonAction(new Qt3DInput::QAction()) - , m_fineMotionAction(new Qt3DInput::QAction()) - , m_rxAxis(new Qt3DInput::QAxis()) - , m_ryAxis(new Qt3DInput::QAxis()) - , m_txAxis(new Qt3DInput::QAxis()) - , m_tyAxis(new Qt3DInput::QAxis()) - , m_tzAxis(new Qt3DInput::QAxis()) - , m_leftMouseButtonInput(new Qt3DInput::QActionInput()) - , m_fineMotionKeyInput(new Qt3DInput::QActionInput()) - , m_mouseRxInput(new Qt3DInput::QAnalogAxisInput()) - , m_mouseRyInput(new Qt3DInput::QAnalogAxisInput()) - , m_mouseTzXInput(new Qt3DInput::QAnalogAxisInput()) - , m_mouseTzYInput(new Qt3DInput::QAnalogAxisInput()) - , m_keyboardTxPosInput(new Qt3DInput::QButtonAxisInput()) - , m_keyboardTyPosInput(new Qt3DInput::QButtonAxisInput()) - , m_keyboardTzPosInput(new Qt3DInput::QButtonAxisInput()) - , m_keyboardTxNegInput(new Qt3DInput::QButtonAxisInput()) - , m_keyboardTyNegInput(new Qt3DInput::QButtonAxisInput()) - , m_keyboardTzNegInput(new Qt3DInput::QButtonAxisInput()) - , m_keyboardDevice(new Qt3DInput::QKeyboardDevice()) - , m_mouseDevice(new Qt3DInput::QMouseDevice()) - , m_logicalDevice(new Qt3DInput::QLogicalDevice()) - , m_frameAction(new Qt3DLogic::QFrameAction()) - , m_linearSpeed(10.0f) - , m_lookSpeed(180.0f) - , m_acceleration(-1.0f) - , m_deceleration(-1.0f) - , m_firstPersonUp(QVector3D(0.0f, 1.0f, 0.0f)) -{} - -void QFirstPersonCameraControllerPrivate::init() -{ - //// Actions - - // Left Mouse Button Action - m_leftMouseButtonInput->setButtons(QVector() << Qt::LeftButton); - m_leftMouseButtonInput->setSourceDevice(m_mouseDevice); - m_leftMouseButtonAction->addInput(m_leftMouseButtonInput); - - // Fine Motion Action - m_fineMotionKeyInput->setButtons(QVector() << Qt::Key_Shift); - m_fineMotionKeyInput->setSourceDevice(m_keyboardDevice); - m_fineMotionAction->addInput(m_fineMotionKeyInput); - - //// Axes - - // Mouse X - m_mouseRxInput->setAxis(Qt3DInput::QMouseDevice::X); - m_mouseRxInput->setSourceDevice(m_mouseDevice); - m_rxAxis->addInput(m_mouseRxInput); - - // Mouse Y - m_mouseRyInput->setAxis(Qt3DInput::QMouseDevice::Y); - m_mouseRyInput->setSourceDevice(m_mouseDevice); - m_ryAxis->addInput(m_mouseRyInput); - - // Mouse Wheel X - m_mouseTzXInput->setAxis(Qt3DInput::QMouseDevice::WheelX); - m_mouseTzXInput->setSourceDevice(m_mouseDevice); - m_tzAxis->addInput(m_mouseTzXInput); - - // Mouse Wheel Y - m_mouseTzYInput->setAxis(Qt3DInput::QMouseDevice::WheelY); - m_mouseTzYInput->setSourceDevice(m_mouseDevice); - m_tzAxis->addInput(m_mouseTzYInput); - - // Keyboard Pos Tx - m_keyboardTxPosInput->setButtons(QVector() << Qt::Key_Right); - m_keyboardTxPosInput->setScale(1.0f); - m_keyboardTxPosInput->setSourceDevice(m_keyboardDevice); - m_txAxis->addInput(m_keyboardTxPosInput); - - // Keyboard Pos Ty - m_keyboardTyPosInput->setButtons(QVector() << Qt::Key_PageUp); - m_keyboardTyPosInput->setScale(1.0f); - m_keyboardTyPosInput->setSourceDevice(m_keyboardDevice); - m_tyAxis->addInput(m_keyboardTyPosInput); - - // Keyboard Pos Tz - m_keyboardTzPosInput->setButtons(QVector() << Qt::Key_Up); - m_keyboardTzPosInput->setScale(1.0f); - m_keyboardTzPosInput->setSourceDevice(m_keyboardDevice); - m_tzAxis->addInput(m_keyboardTzPosInput); - - // Keyboard Neg Tx - m_keyboardTxNegInput->setButtons(QVector() << Qt::Key_Left); - m_keyboardTxNegInput->setScale(-1.0f); - m_keyboardTxNegInput->setSourceDevice(m_keyboardDevice); - m_txAxis->addInput(m_keyboardTxNegInput); - - // Keyboard Neg Ty - m_keyboardTyNegInput->setButtons(QVector() << Qt::Key_PageDown); - m_keyboardTyNegInput->setScale(-1.0f); - m_keyboardTyNegInput->setSourceDevice(m_keyboardDevice); - m_tyAxis->addInput(m_keyboardTyNegInput); - - // Keyboard Neg Tz - m_keyboardTzNegInput->setButtons(QVector() << Qt::Key_Down); - m_keyboardTzNegInput->setScale(-1.0f); - m_keyboardTzNegInput->setSourceDevice(m_keyboardDevice); - m_tzAxis->addInput(m_keyboardTzNegInput); - - //// Logical Device - - m_logicalDevice->addAction(m_fineMotionAction); - m_logicalDevice->addAction(m_leftMouseButtonAction); - m_logicalDevice->addAxis(m_rxAxis); - m_logicalDevice->addAxis(m_ryAxis); - m_logicalDevice->addAxis(m_txAxis); - m_logicalDevice->addAxis(m_tyAxis); - m_logicalDevice->addAxis(m_tzAxis); - - applyAccelerations(); - - Q_Q(QFirstPersonCameraController); - //// FrameAction - - QObject::connect(m_frameAction, SIGNAL(triggered(float)), - q, SLOT(_q_onTriggered(float))); - - // Disable the logical device when the entity is disabled - QObject::connect(q, &Qt3DCore::QEntity::enabledChanged, - m_logicalDevice, &Qt3DInput::QLogicalDevice::setEnabled); - - q->addComponent(m_frameAction); - q->addComponent(m_logicalDevice); -} - -void QFirstPersonCameraControllerPrivate::applyAccelerations() -{ - const auto inputs = { - m_keyboardTxPosInput, - m_keyboardTyPosInput, - m_keyboardTzPosInput, - m_keyboardTxNegInput, - m_keyboardTyNegInput, - m_keyboardTzNegInput - }; - - for (auto input : inputs) { - input->setAcceleration(m_acceleration); - input->setDeceleration(m_deceleration); - } -} - -void QFirstPersonCameraControllerPrivate::_q_onTriggered(float dt) -{ - if (m_camera != nullptr) { - m_camera->translate(QVector3D(m_txAxis->value() * m_linearSpeed, - m_tyAxis->value() * m_linearSpeed, - m_tzAxis->value() * m_linearSpeed) * dt); - if (m_leftMouseButtonAction->isActive()) { - float lookSpeed = m_lookSpeed; - if (m_fineMotionAction->isActive()) - lookSpeed *= 0.2f; - m_camera->pan(m_rxAxis->value() * lookSpeed * dt, m_firstPersonUp); - m_camera->tilt(m_ryAxis->value() * lookSpeed * dt); - } - } -} - /*! \class Qt3DExtras::QFirstPersonCameraController \brief The QFirstPersonCameraController class allows controlling the scene camera @@ -251,129 +76,35 @@ void QFirstPersonCameraControllerPrivate::_q_onTriggered(float dt) */ QFirstPersonCameraController::QFirstPersonCameraController(Qt3DCore::QNode *parent) - : Qt3DCore::QEntity(*new QFirstPersonCameraControllerPrivate, parent) + : QAbstractCameraController(parent) { - Q_D(QFirstPersonCameraController); - d->init(); } QFirstPersonCameraController::~QFirstPersonCameraController() { } -/*! - \property QFirstPersonCameraController::camera - - Holds the currently controlled camera. -*/ -Qt3DRender::QCamera *QFirstPersonCameraController::camera() const -{ - Q_D(const QFirstPersonCameraController); - return d->m_camera; -} - -/*! - \property QFirstPersonCameraController::linearSpeed - Holds the current linear speed of the camera controller. Linear speed determines the - movement speed of the camera. -*/ -float QFirstPersonCameraController::linearSpeed() const +void QFirstPersonCameraController::moveCamera(const QAbstractCameraController::InputState &state, float dt) { - Q_D(const QFirstPersonCameraController); - return d->m_linearSpeed; -} - -/*! - \property QFirstPersonCameraController::lookSpeed - - Holds the current look speed of the camera controller. The look speed determines the turn rate - of the camera pan and tilt. -*/ -float QFirstPersonCameraController::lookSpeed() const -{ - Q_D(const QFirstPersonCameraController); - return d->m_lookSpeed; -} - -/*! - \property QFirstPersonCameraController::acceleration - - Holds the current acceleration of the camera controller. -*/ -float QFirstPersonCameraController::acceleration() const -{ - Q_D(const QFirstPersonCameraController); - return d->m_acceleration; -} - -/*! - \property QFirstPersonCameraController::deceleration - - Holds the current deceleration of the camera controller. -*/ -float QFirstPersonCameraController::deceleration() const -{ - Q_D(const QFirstPersonCameraController); - return d->m_deceleration; -} - -void QFirstPersonCameraController::setCamera(Qt3DRender::QCamera *camera) -{ - Q_D(QFirstPersonCameraController); - if (d->m_camera != camera) { - - if (d->m_camera) - d->unregisterDestructionHelper(d->m_camera); - - if (camera && !camera->parent()) - camera->setParent(this); - - d->m_camera = camera; - - // Ensures proper bookkeeping - if (d->m_camera) - d->registerDestructionHelper(d->m_camera, &QFirstPersonCameraController::setCamera, d->m_camera); - - emit cameraChanged(); - } -} - -void QFirstPersonCameraController::setLinearSpeed(float linearSpeed) -{ - Q_D(QFirstPersonCameraController); - if (d->m_linearSpeed != linearSpeed) { - d->m_linearSpeed = linearSpeed; - emit linearSpeedChanged(); - } -} - -void QFirstPersonCameraController::setLookSpeed(float lookSpeed) -{ - Q_D(QFirstPersonCameraController); - if (d->m_lookSpeed != lookSpeed) { - d->m_lookSpeed = lookSpeed; - emit lookSpeedChanged(); - } -} + Qt3DRender::QCamera *theCamera = camera(); + + if (theCamera == nullptr) + return; + + theCamera->translate(QVector3D(state.txAxisValue * linearSpeed(), + state.tyAxisValue * linearSpeed(), + state.tzAxisValue * linearSpeed()) * dt); + if (state.leftMouseButtonActive) { + float theLookSpeed = lookSpeed(); + if (state.shiftKeyActive) { + theLookSpeed *= 0.2f; + } -void QFirstPersonCameraController::setAcceleration(float acceleration) -{ - Q_D(QFirstPersonCameraController); - if (d->m_acceleration != acceleration) { - d->m_acceleration = acceleration; - d->applyAccelerations(); - emit accelerationChanged(acceleration); - } -} + const QVector3D upVector(0.0f, 1.0f, 0.0f); -void QFirstPersonCameraController::setDeceleration(float deceleration) -{ - Q_D(QFirstPersonCameraController); - if (d->m_deceleration != deceleration) { - d->m_deceleration = deceleration; - d->applyAccelerations(); - emit decelerationChanged(deceleration); + theCamera->pan(state.rxAxisValue * theLookSpeed * dt, upVector); + theCamera->tilt(state.ryAxisValue * theLookSpeed * dt); } } diff --git a/src/extras/defaults/qfirstpersoncameracontroller.h b/src/extras/defaults/qfirstpersoncameracontroller.h index 3f7a6acc4..60edf7cb8 100644 --- a/src/extras/defaults/qfirstpersoncameracontroller.h +++ b/src/extras/defaults/qfirstpersoncameracontroller.h @@ -37,53 +37,22 @@ #ifndef QT3DEXTRAS_QFIRSTPERSONCAMERACONTROLLER_H #define QT3DEXTRAS_QFIRSTPERSONCAMERACONTROLLER_H -#include -#include +#include QT_BEGIN_NAMESPACE -namespace Qt3DRender { -class QCamera; -} - namespace Qt3DExtras { -class QFirstPersonCameraControllerPrivate; - -class QT3DEXTRASSHARED_EXPORT QFirstPersonCameraController : public Qt3DCore::QEntity +class QT3DEXTRASSHARED_EXPORT QFirstPersonCameraController : public QAbstractCameraController { Q_OBJECT - Q_PROPERTY(Qt3DRender::QCamera *camera READ camera WRITE setCamera NOTIFY cameraChanged) - Q_PROPERTY(float linearSpeed READ linearSpeed WRITE setLinearSpeed NOTIFY linearSpeedChanged) - Q_PROPERTY(float lookSpeed READ lookSpeed WRITE setLookSpeed NOTIFY lookSpeedChanged) - Q_PROPERTY(float acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged) - Q_PROPERTY(float deceleration READ deceleration WRITE setDeceleration NOTIFY decelerationChanged) + public: explicit QFirstPersonCameraController(Qt3DCore::QNode *parent = nullptr); ~QFirstPersonCameraController(); - Qt3DRender::QCamera *camera() const; - float linearSpeed() const; - float lookSpeed() const; - float acceleration() const; - float deceleration() const; - - void setCamera(Qt3DRender::QCamera *camera); - void setLinearSpeed(float linearSpeed); - void setLookSpeed(float lookSpeed); - void setAcceleration(float acceleration); - void setDeceleration(float deceleration); - -Q_SIGNALS: - void cameraChanged(); - void linearSpeedChanged(); - void lookSpeedChanged(); - void accelerationChanged(float acceleration); - void decelerationChanged(float deceleration); - private: - Q_DECLARE_PRIVATE(QFirstPersonCameraController) - Q_PRIVATE_SLOT(d_func(), void _q_onTriggered(float)) + void moveCamera(const QAbstractCameraController::InputState &state, float dt) override; }; } // Qt3DExtras diff --git a/src/extras/defaults/qfirstpersoncameracontroller_p.h b/src/extras/defaults/qfirstpersoncameracontroller_p.h deleted file mode 100644 index 48a7c7998..000000000 --- a/src/extras/defaults/qfirstpersoncameracontroller_p.h +++ /dev/null @@ -1,152 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DEXTRAS_QFIRSTPERSONCAMERACONTROLLER_P_H -#define QT3DEXTRAS_QFIRSTPERSONCAMERACONTROLLER_P_H - -#include -#include - -#include - - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { -class QCamera; -} - -namespace Qt3DLogic { -class QFrameAction; -} - -namespace Qt3DInput { - -class QKeyboardDevice; -class QMouseDevice; -class QLogicalDevice; -class QAction; -class QActionInput; -class QAxis; -class QAnalogAxisInput; -class QButtonAxisInput; -class QAxisActionHandler; - -} - -namespace Qt3DExtras { - -class QFirstPersonCameraControllerPrivate : public Qt3DCore::QEntityPrivate -{ -public: - QFirstPersonCameraControllerPrivate(); - - void init(); - void applyAccelerations(); - - Qt3DRender::QCamera *m_camera; - - Qt3DInput::QAction *m_leftMouseButtonAction; - Qt3DInput::QAction *m_fineMotionAction; - - Qt3DInput::QAxis *m_rxAxis; - Qt3DInput::QAxis *m_ryAxis; - Qt3DInput::QAxis *m_txAxis; - Qt3DInput::QAxis *m_tyAxis; - Qt3DInput::QAxis *m_tzAxis; - - Qt3DInput::QActionInput *m_leftMouseButtonInput; - Qt3DInput::QActionInput *m_fineMotionKeyInput; - - Qt3DInput::QAnalogAxisInput *m_mouseRxInput; - Qt3DInput::QAnalogAxisInput *m_mouseRyInput; - Qt3DInput::QAnalogAxisInput *m_mouseTzXInput; - Qt3DInput::QAnalogAxisInput *m_mouseTzYInput; - Qt3DInput::QButtonAxisInput *m_keyboardTxPosInput; - Qt3DInput::QButtonAxisInput *m_keyboardTyPosInput; - Qt3DInput::QButtonAxisInput *m_keyboardTzPosInput; - Qt3DInput::QButtonAxisInput *m_keyboardTxNegInput; - Qt3DInput::QButtonAxisInput *m_keyboardTyNegInput; - Qt3DInput::QButtonAxisInput *m_keyboardTzNegInput; - - Qt3DInput::QKeyboardDevice *m_keyboardDevice; - Qt3DInput::QMouseDevice *m_mouseDevice; - - Qt3DInput::QLogicalDevice *m_logicalDevice; - - Qt3DLogic::QFrameAction *m_frameAction; - - float m_linearSpeed; - float m_lookSpeed; - float m_acceleration; - float m_deceleration; - QVector3D m_firstPersonUp; - - void _q_onTriggered(float); - - Q_DECLARE_PUBLIC(QFirstPersonCameraController) -}; - -} // Qt3DInput - -QT_END_NAMESPACE - -#endif // QT3DINPUT_QFIRSTPERSONCAMERACONTROLLER_P_H diff --git a/src/extras/defaults/qorbitcameracontroller.cpp b/src/extras/defaults/qorbitcameracontroller.cpp index 565a75ea1..03e9a290b 100644 --- a/src/extras/defaults/qorbitcameracontroller.cpp +++ b/src/extras/defaults/qorbitcameracontroller.cpp @@ -38,22 +38,15 @@ #include "qorbitcameracontroller_p.h" #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include QT_BEGIN_NAMESPACE namespace Qt3DExtras { +QOrbitCameraControllerPrivate::QOrbitCameraControllerPrivate() + : m_zoomInLimit(2.0f) +{} + /*! \class Qt3DExtras::QOrbitCameraController \brief The QOrbitCameraController class allows controlling the scene camera along orbital path. @@ -99,251 +92,20 @@ namespace Qt3DExtras { \endtable */ -QOrbitCameraControllerPrivate::QOrbitCameraControllerPrivate() - : Qt3DCore::QEntityPrivate() - , m_camera(nullptr) - , m_leftMouseButtonAction(new Qt3DInput::QAction()) - , m_rightMouseButtonAction(new Qt3DInput::QAction()) - , m_altButtonAction(new Qt3DInput::QAction()) - , m_shiftButtonAction(new Qt3DInput::QAction()) - , m_rxAxis(new Qt3DInput::QAxis()) - , m_ryAxis(new Qt3DInput::QAxis()) - , m_txAxis(new Qt3DInput::QAxis()) - , m_tyAxis(new Qt3DInput::QAxis()) - , m_tzAxis(new Qt3DInput::QAxis()) - , m_leftMouseButtonInput(new Qt3DInput::QActionInput()) - , m_rightMouseButtonInput(new Qt3DInput::QActionInput()) - , m_altButtonInput(new Qt3DInput::QActionInput()) - , m_shiftButtonInput(new Qt3DInput::QActionInput()) - , m_mouseRxInput(new Qt3DInput::QAnalogAxisInput()) - , m_mouseRyInput(new Qt3DInput::QAnalogAxisInput()) - , m_mouseTzXInput(new Qt3DInput::QAnalogAxisInput()) - , m_mouseTzYInput(new Qt3DInput::QAnalogAxisInput()) - , m_keyboardTxPosInput(new Qt3DInput::QButtonAxisInput()) - , m_keyboardTyPosInput(new Qt3DInput::QButtonAxisInput()) - , m_keyboardTzPosInput(new Qt3DInput::QButtonAxisInput()) - , m_keyboardTxNegInput(new Qt3DInput::QButtonAxisInput()) - , m_keyboardTyNegInput(new Qt3DInput::QButtonAxisInput()) - , m_keyboardTzNegInput(new Qt3DInput::QButtonAxisInput()) - , m_keyboardDevice(new Qt3DInput::QKeyboardDevice()) - , m_mouseDevice(new Qt3DInput::QMouseDevice()) - , m_logicalDevice(new Qt3DInput::QLogicalDevice()) - , m_frameAction(new Qt3DLogic::QFrameAction()) - , m_linearSpeed(10.0f) - , m_lookSpeed(180.0f) - , m_zoomInLimit(2.0f) - , m_cameraUp(QVector3D(0.0f, 1.0f, 0.0f)) -{} - -void QOrbitCameraControllerPrivate::init() -{ - //// Actions - - // Left Mouse Button Action - m_leftMouseButtonInput->setButtons(QVector() << Qt::LeftButton); - m_leftMouseButtonInput->setSourceDevice(m_mouseDevice); - m_leftMouseButtonAction->addInput(m_leftMouseButtonInput); - - // Right Mouse Button Action - m_rightMouseButtonInput->setButtons(QVector() << Qt::RightButton); - m_rightMouseButtonInput->setSourceDevice(m_mouseDevice); - m_rightMouseButtonAction->addInput(m_rightMouseButtonInput); - - // Alt Button Action - m_altButtonInput->setButtons(QVector() << Qt::Key_Alt); - m_altButtonInput->setSourceDevice(m_keyboardDevice); - m_altButtonAction->addInput(m_altButtonInput); - - // Shift Button Action - m_shiftButtonInput->setButtons(QVector() << Qt::Key_Shift); - m_shiftButtonInput->setSourceDevice(m_keyboardDevice); - m_shiftButtonAction->addInput(m_shiftButtonInput); - - //// Axes - - // Mouse X - m_mouseRxInput->setAxis(Qt3DInput::QMouseDevice::X); - m_mouseRxInput->setSourceDevice(m_mouseDevice); - m_rxAxis->addInput(m_mouseRxInput); - - // Mouse Y - m_mouseRyInput->setAxis(Qt3DInput::QMouseDevice::Y); - m_mouseRyInput->setSourceDevice(m_mouseDevice); - m_ryAxis->addInput(m_mouseRyInput); - - // Mouse Wheel X - m_mouseTzXInput->setAxis(Qt3DInput::QMouseDevice::WheelX); - m_mouseTzXInput->setSourceDevice(m_mouseDevice); - m_tzAxis->addInput(m_mouseTzXInput); - - // Mouse Wheel Y - m_mouseTzYInput->setAxis(Qt3DInput::QMouseDevice::WheelY); - m_mouseTzYInput->setSourceDevice(m_mouseDevice); - m_tzAxis->addInput(m_mouseTzYInput); - - // Keyboard Pos Tx - m_keyboardTxPosInput->setButtons(QVector() << Qt::Key_Right); - m_keyboardTxPosInput->setScale(1.0f); - m_keyboardTxPosInput->setSourceDevice(m_keyboardDevice); - m_txAxis->addInput(m_keyboardTxPosInput); - - // Keyboard Pos Tz - m_keyboardTzPosInput->setButtons(QVector() << Qt::Key_PageUp); - m_keyboardTzPosInput->setScale(1.0f); - m_keyboardTzPosInput->setSourceDevice(m_keyboardDevice); - m_tzAxis->addInput(m_keyboardTzPosInput); - - // Keyboard Pos Ty - m_keyboardTyPosInput->setButtons(QVector() << Qt::Key_Up); - m_keyboardTyPosInput->setScale(1.0f); - m_keyboardTyPosInput->setSourceDevice(m_keyboardDevice); - m_tyAxis->addInput(m_keyboardTyPosInput); - - // Keyboard Neg Tx - m_keyboardTxNegInput->setButtons(QVector() << Qt::Key_Left); - m_keyboardTxNegInput->setScale(-1.0f); - m_keyboardTxNegInput->setSourceDevice(m_keyboardDevice); - m_txAxis->addInput(m_keyboardTxNegInput); - - // Keyboard Neg Tz - m_keyboardTzNegInput->setButtons(QVector() << Qt::Key_PageDown); - m_keyboardTzNegInput->setScale(-1.0f); - m_keyboardTzNegInput->setSourceDevice(m_keyboardDevice); - m_tzAxis->addInput(m_keyboardTzNegInput); - - // Keyboard Neg Ty - m_keyboardTyNegInput->setButtons(QVector() << Qt::Key_Down); - m_keyboardTyNegInput->setScale(-1.0f); - m_keyboardTyNegInput->setSourceDevice(m_keyboardDevice); - m_tyAxis->addInput(m_keyboardTyNegInput); - - //// Logical Device - - m_logicalDevice->addAction(m_leftMouseButtonAction); - m_logicalDevice->addAction(m_rightMouseButtonAction); - m_logicalDevice->addAction(m_altButtonAction); - m_logicalDevice->addAction(m_shiftButtonAction); - m_logicalDevice->addAxis(m_rxAxis); - m_logicalDevice->addAxis(m_ryAxis); - m_logicalDevice->addAxis(m_txAxis); - m_logicalDevice->addAxis(m_tyAxis); - m_logicalDevice->addAxis(m_tzAxis); - - Q_Q(QOrbitCameraController); - //// FrameAction - - QObject::connect(m_frameAction, SIGNAL(triggered(float)), - q, SLOT(_q_onTriggered(float))); - - // Disable the logical device when the entity is disabled - QObject::connect(q, &Qt3DCore::QEntity::enabledChanged, - m_logicalDevice, &Qt3DInput::QLogicalDevice::setEnabled); - - q->addComponent(m_frameAction); - q->addComponent(m_logicalDevice); -} - -float clampInputs(float input1, float input2) -{ - float axisValue = input1 + input2; - return (axisValue < -1) ? -1 : (axisValue > 1) ? 1 : axisValue; -} - -float zoomDistance(QVector3D firstPoint, QVector3D secondPoint) -{ - return (secondPoint - firstPoint).lengthSquared(); -} - -void QOrbitCameraControllerPrivate::_q_onTriggered(float dt) -{ - if (m_camera != nullptr) { - // Mouse input - if (m_leftMouseButtonAction->isActive()) { - if (m_rightMouseButtonAction->isActive()) { - if ( zoomDistance(m_camera->position(), m_camera->viewCenter()) > m_zoomInLimit * m_zoomInLimit) { - // Dolly up to limit - m_camera->translate(QVector3D(0, 0, m_ryAxis->value()), m_camera->DontTranslateViewCenter); - } else { - m_camera->translate(QVector3D(0, 0, -0.5), m_camera->DontTranslateViewCenter); - } - } else { - // Translate - m_camera->translate(QVector3D(clampInputs(m_rxAxis->value(), m_txAxis->value()) * m_linearSpeed, - clampInputs(m_ryAxis->value(), m_tyAxis->value()) * m_linearSpeed, - 0) * dt); - } - return; - } - else if (m_rightMouseButtonAction->isActive()) { - // Orbit - m_camera->panAboutViewCenter((m_rxAxis->value() * m_lookSpeed) * dt, m_cameraUp); - m_camera->tiltAboutViewCenter((m_ryAxis->value() * m_lookSpeed) * dt); - } - // Keyboard Input - if (m_altButtonAction->isActive()) { - // Orbit - m_camera->panAboutViewCenter((m_txAxis->value() * m_lookSpeed) * dt, m_cameraUp); - m_camera->tiltAboutViewCenter((m_tyAxis->value() * m_lookSpeed) * dt); - } else if (m_shiftButtonAction->isActive()) { - if (zoomDistance(m_camera->position(), m_camera->viewCenter()) > m_zoomInLimit * m_zoomInLimit) { - // Dolly - m_camera->translate(QVector3D(0, 0, m_tyAxis->value()), m_camera->DontTranslateViewCenter); - } else { - m_camera->translate(QVector3D(0, 0, -0.5), m_camera->DontTranslateViewCenter); - } - } else { - // Translate - m_camera->translate(QVector3D(clampInputs(m_leftMouseButtonAction->isActive() ? m_rxAxis->value() : 0, m_txAxis->value()) * m_linearSpeed, - clampInputs(m_leftMouseButtonAction->isActive() ? m_ryAxis->value() : 0, m_tyAxis->value()) * m_linearSpeed, - m_tzAxis->value() * m_linearSpeed) * dt); - } - } -} - QOrbitCameraController::QOrbitCameraController(Qt3DCore::QNode *parent) - : Qt3DCore::QEntity(*new QOrbitCameraControllerPrivate, parent) + : QOrbitCameraController(*new QOrbitCameraControllerPrivate, parent) { - Q_D(QOrbitCameraController); - d->init(); } -QOrbitCameraController::~QOrbitCameraController() +/*! \internal + */ +QOrbitCameraController::QOrbitCameraController(QOrbitCameraControllerPrivate &dd, Qt3DCore::QNode *parent) + : QAbstractCameraController(dd, parent) { } -/*! - \property QOrbitCameraController::camera - - Holds the currently controlled camera. -*/ -Qt3DRender::QCamera *QOrbitCameraController::camera() const -{ - Q_D(const QOrbitCameraController); - return d->m_camera; -} - -/*! - \property QOrbitCameraController::linearSpeed - - Holds the current linear speed of the camera controller. Linear speed determines the - movement speed of the camera. -*/ -float QOrbitCameraController::linearSpeed() const -{ - Q_D(const QOrbitCameraController); - return d->m_linearSpeed; -} - -/*! - \property QOrbitCameraController::lookSpeed - - Holds the current look speed of the camera controller. The look speed determines the turn rate - of the camera pan and tilt. -*/ -float QOrbitCameraController::lookSpeed() const +QOrbitCameraController::~QOrbitCameraController() { - Q_D(const QOrbitCameraController); - return d->m_lookSpeed; } /*! @@ -358,51 +120,77 @@ float QOrbitCameraController::zoomInLimit() const return d->m_zoomInLimit; } -void QOrbitCameraController::setCamera(Qt3DRender::QCamera *camera) +void QOrbitCameraController::setZoomInLimit(float zoomInLimit) { Q_D(QOrbitCameraController); - if (d->m_camera != camera) { - - if (d->m_camera) - d->unregisterDestructionHelper(d->m_camera); - - if (camera && !camera->parent()) - camera->setParent(this); - - d->m_camera = camera; - - // Ensures proper bookkeeping - if (d->m_camera) - d->registerDestructionHelper(d->m_camera, &QOrbitCameraController::setCamera, d->m_camera); - - emit cameraChanged(); + if (d->m_zoomInLimit != zoomInLimit) { + d->m_zoomInLimit = zoomInLimit; + emit zoomInLimitChanged(); } } -void QOrbitCameraController::setLinearSpeed(float linearSpeed) +inline float clampInputs(float input1, float input2) { - Q_D(QOrbitCameraController); - if (d->m_linearSpeed != linearSpeed) { - d->m_linearSpeed = linearSpeed; - emit linearSpeedChanged(); - } + float axisValue = input1 + input2; + return (axisValue < -1) ? -1 : (axisValue > 1) ? 1 : axisValue; } -void QOrbitCameraController::setLookSpeed(float lookSpeed) +inline float zoomDistance(QVector3D firstPoint, QVector3D secondPoint) { - Q_D(QOrbitCameraController); - if (d->m_lookSpeed != lookSpeed) { - d->m_lookSpeed = lookSpeed; - emit lookSpeedChanged(); - } + return (secondPoint - firstPoint).lengthSquared(); } -void QOrbitCameraController::setZoomInLimit(float zoomInLimit) +void QOrbitCameraController::moveCamera(const QAbstractCameraController::InputState &state, float dt) { Q_D(QOrbitCameraController); - if (d->m_zoomInLimit != zoomInLimit) { - d->m_zoomInLimit = zoomInLimit; - emit zoomInLimitChanged(); + + Qt3DRender::QCamera *theCamera = camera(); + + if (theCamera == nullptr) + return; + + const QVector3D upVector(0.0f, 1.0f, 0.0f); + + // Mouse input + if (state.leftMouseButtonActive) { + if (state.rightMouseButtonActive) { + if ( zoomDistance(camera()->position(), theCamera->viewCenter()) > d->m_zoomInLimit * d->m_zoomInLimit) { + // Dolly up to limit + theCamera->translate(QVector3D(0, 0, state.ryAxisValue), theCamera->DontTranslateViewCenter); + } else { + theCamera->translate(QVector3D(0, 0, -0.5), theCamera->DontTranslateViewCenter); + } + } else { + // Translate + theCamera->translate(QVector3D(clampInputs(state.rxAxisValue, state.txAxisValue) * linearSpeed(), + clampInputs(state.ryAxisValue, state.tyAxisValue) * linearSpeed(), + 0) * dt); + } + return; + } + else if (state.rightMouseButtonActive) { + // Orbit + theCamera->panAboutViewCenter((state.rxAxisValue * lookSpeed()) * dt, upVector); + theCamera->tiltAboutViewCenter((state.ryAxisValue * lookSpeed()) * dt); + } + + // Keyboard Input + if (state.altKeyActive) { + // Orbit + theCamera->panAboutViewCenter((state.txAxisValue * lookSpeed()) * dt, upVector); + theCamera->tiltAboutViewCenter((state.tyAxisValue * lookSpeed()) * dt); + } else if (state.shiftKeyActive) { + if (zoomDistance(camera()->position(), theCamera->viewCenter()) > d->m_zoomInLimit * d->m_zoomInLimit) { + // Dolly + theCamera->translate(QVector3D(0, 0, state.tyAxisValue), theCamera->DontTranslateViewCenter); + } else { + theCamera->translate(QVector3D(0, 0, -0.5), theCamera->DontTranslateViewCenter); + } + } else { + // Translate + theCamera->translate(QVector3D(clampInputs(state.leftMouseButtonActive ? state.rxAxisValue : 0, state.txAxisValue) * linearSpeed(), + clampInputs(state.leftMouseButtonActive ? state.ryAxisValue : 0, state.tyAxisValue) * linearSpeed(), + state.tzAxisValue * linearSpeed()) * dt); } } diff --git a/src/extras/defaults/qorbitcameracontroller.h b/src/extras/defaults/qorbitcameracontroller.h index 7cb8b3eb7..684bfddf1 100644 --- a/src/extras/defaults/qorbitcameracontroller.h +++ b/src/extras/defaults/qorbitcameracontroller.h @@ -37,50 +37,38 @@ #ifndef QT3DEXTRAS_QORBITCAMERACONTROLLER_H #define QT3DEXTRAS_QORBITCAMERACONTROLLER_H -#include -#include +#include QT_BEGIN_NAMESPACE -namespace Qt3DRender { -class QCamera; -} - namespace Qt3DExtras { class QOrbitCameraControllerPrivate; -class QT3DEXTRASSHARED_EXPORT QOrbitCameraController : public Qt3DCore::QEntity +class QT3DEXTRASSHARED_EXPORT QOrbitCameraController : public QAbstractCameraController { Q_OBJECT - Q_PROPERTY(Qt3DRender::QCamera *camera READ camera WRITE setCamera NOTIFY cameraChanged) - Q_PROPERTY(float linearSpeed READ linearSpeed WRITE setLinearSpeed NOTIFY linearSpeedChanged) - Q_PROPERTY(float lookSpeed READ lookSpeed WRITE setLookSpeed NOTIFY lookSpeedChanged) Q_PROPERTY(float zoomInLimit READ zoomInLimit WRITE setZoomInLimit NOTIFY zoomInLimitChanged) public: explicit QOrbitCameraController(Qt3DCore::QNode *parent = nullptr); ~QOrbitCameraController(); - Qt3DRender::QCamera *camera() const; - float linearSpeed() const; - float lookSpeed() const; float zoomInLimit() const; - void setCamera(Qt3DRender::QCamera *camera); - void setLinearSpeed(float linearSpeed); - void setLookSpeed(float lookSpeed); void setZoomInLimit(float zoomInLimit); Q_SIGNALS: - void cameraChanged(); - void linearSpeedChanged(); - void lookSpeedChanged(); void zoomInLimitChanged(); +protected: + QOrbitCameraController(QOrbitCameraControllerPrivate &dd, Qt3DCore::QNode *parent = nullptr); + +private: + void moveCamera(const QAbstractCameraController::InputState &state, float dt) override; + private: Q_DECLARE_PRIVATE(QOrbitCameraController) - Q_PRIVATE_SLOT(d_func(), void _q_onTriggered(float)) }; } // Qt3DExtras diff --git a/src/extras/defaults/qorbitcameracontroller_p.h b/src/extras/defaults/qorbitcameracontroller_p.h index 8105d4375..1e4e3d4d2 100644 --- a/src/extras/defaults/qorbitcameracontroller_p.h +++ b/src/extras/defaults/qorbitcameracontroller_p.h @@ -48,88 +48,25 @@ // We mean it. // -#include -#include - -#include +#include QT_BEGIN_NAMESPACE -namespace Qt3DRender { -class QCamera; -} - -namespace Qt3DLogic { -class QFrameAction; -} - -namespace Qt3DInput { - -class QKeyboardDevice; -class QMouseDevice; -class QLogicalDevice; -class QAction; -class QActionInput; -class QAxis; -class QAnalogAxisInput; -class QButtonAxisInput; -class QAxisActionHandler; - -} - namespace Qt3DExtras { -class QOrbitCameraControllerPrivate : public Qt3DCore::QEntityPrivate +class QOrbitCameraControllerPrivate : public QAbstractCameraControllerPrivate { + Q_DECLARE_PUBLIC(QOrbitCameraController) + public: QOrbitCameraControllerPrivate(); void init(); - Qt3DRender::QCamera *m_camera; - - Qt3DInput::QAction *m_leftMouseButtonAction; - Qt3DInput::QAction *m_rightMouseButtonAction; - Qt3DInput::QAction *m_altButtonAction; - Qt3DInput::QAction *m_shiftButtonAction; - - Qt3DInput::QAxis *m_rxAxis; - Qt3DInput::QAxis *m_ryAxis; - Qt3DInput::QAxis *m_txAxis; - Qt3DInput::QAxis *m_tyAxis; - Qt3DInput::QAxis *m_tzAxis; - - Qt3DInput::QActionInput *m_leftMouseButtonInput; - Qt3DInput::QActionInput *m_rightMouseButtonInput; - Qt3DInput::QActionInput *m_altButtonInput; - Qt3DInput::QActionInput *m_shiftButtonInput; - - Qt3DInput::QAnalogAxisInput *m_mouseRxInput; - Qt3DInput::QAnalogAxisInput *m_mouseRyInput; - Qt3DInput::QAnalogAxisInput *m_mouseTzXInput; - Qt3DInput::QAnalogAxisInput *m_mouseTzYInput; - Qt3DInput::QButtonAxisInput *m_keyboardTxPosInput; - Qt3DInput::QButtonAxisInput *m_keyboardTyPosInput; - Qt3DInput::QButtonAxisInput *m_keyboardTzPosInput; - Qt3DInput::QButtonAxisInput *m_keyboardTxNegInput; - Qt3DInput::QButtonAxisInput *m_keyboardTyNegInput; - Qt3DInput::QButtonAxisInput *m_keyboardTzNegInput; - - Qt3DInput::QKeyboardDevice *m_keyboardDevice; - Qt3DInput::QMouseDevice *m_mouseDevice; - - Qt3DInput::QLogicalDevice *m_logicalDevice; - - Qt3DLogic::QFrameAction *m_frameAction; - - float m_linearSpeed; - float m_lookSpeed; float m_zoomInLimit; - QVector3D m_cameraUp; - void _q_onTriggered(float); - - Q_DECLARE_PUBLIC(QOrbitCameraController) +private: + QOrbitCameraController *q_ptr; }; } // namespace Qt3DExtras -- cgit v1.2.3