diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2015-12-08 09:51:29 +0000 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2015-12-16 09:47:30 +0000 |
commit | c16863075cc73485d7a66c93e4b8d9fefcaf5f63 (patch) | |
tree | 7b228ce9b444719220ad7faf1f7176b7692ed87c /src/input | |
parent | 4125d98dfa4abdd6533bb7203b7e36a51dc545aa (diff) |
Implement dead zone support
Change-Id: Icd5d31ba690484dc310de872be9df3ec9a520c63
Reviewed-by: Kevin Ottens <kevin.ottens@kdab.com>
Diffstat (limited to 'src/input')
-rw-r--r-- | src/input/backend/keyboardcontroller.cpp | 6 | ||||
-rw-r--r-- | src/input/backend/keyboardcontroller_p.h | 6 | ||||
-rw-r--r-- | src/input/backend/mousecontroller.cpp | 6 | ||||
-rw-r--r-- | src/input/backend/mousecontroller_p.h | 6 | ||||
-rw-r--r-- | src/input/backend/qabstractphysicaldevicebackendnode.cpp | 137 | ||||
-rw-r--r-- | src/input/backend/qabstractphysicaldevicebackendnode.h | 5 | ||||
-rw-r--r-- | src/input/backend/qabstractphysicaldevicebackendnode_p.h | 25 | ||||
-rw-r--r-- | src/input/backend/updateaxisactionjob.cpp | 2 | ||||
-rw-r--r-- | src/input/frontend/qinputaspect.cpp | 4 |
9 files changed, 180 insertions, 17 deletions
diff --git a/src/input/backend/keyboardcontroller.cpp b/src/input/backend/keyboardcontroller.cpp index f397f4c53..30e1a2af3 100644 --- a/src/input/backend/keyboardcontroller.cpp +++ b/src/input/backend/keyboardcontroller.cpp @@ -446,8 +446,9 @@ void KeyboardController::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &) { } -KeyboardControllerFunctor::KeyboardControllerFunctor(InputHandler *handler) - : m_handler(handler) +KeyboardControllerFunctor::KeyboardControllerFunctor(QInputAspect *inputaspect, InputHandler *handler) + : m_inputAspect(inputaspect) + , m_handler(handler) { } @@ -455,6 +456,7 @@ Qt3DCore::QBackendNode *KeyboardControllerFunctor::create(Qt3DCore::QNode *front { KeyboardController *controller = m_handler->keyboardControllerManager()->getOrCreateResource(frontend->id()); controller->setFactory(factory); + controller->setInputAspect(m_inputAspect); controller->setInputHandler(m_handler); controller->setPeer(frontend); m_handler->appendKeyboardController(m_handler->keyboardControllerManager()->lookupHandle(frontend->id())); diff --git a/src/input/backend/keyboardcontroller_p.h b/src/input/backend/keyboardcontroller_p.h index 3c914d98f..3f4f8da53 100644 --- a/src/input/backend/keyboardcontroller_p.h +++ b/src/input/backend/keyboardcontroller_p.h @@ -56,6 +56,9 @@ QT_BEGIN_NAMESPACE namespace Qt3DInput { + +class QInputAspect; + namespace Input { class InputHandler; @@ -267,13 +270,14 @@ private: class KeyboardControllerFunctor : public Qt3DCore::QBackendNodeFunctor { public: - explicit KeyboardControllerFunctor(InputHandler *handler); + explicit KeyboardControllerFunctor(QInputAspect *inputaspect, InputHandler *handler); Qt3DCore::QBackendNode *create(Qt3DCore::QNode *frontend, const Qt3DCore::QBackendNodeFactory *factory) const Q_DECL_OVERRIDE; Qt3DCore::QBackendNode *get(const Qt3DCore::QNodeId &id) const Q_DECL_OVERRIDE; void destroy(const Qt3DCore::QNodeId &id) const Q_DECL_OVERRIDE; private: + QInputAspect *m_inputAspect; InputHandler *m_handler; }; diff --git a/src/input/backend/mousecontroller.cpp b/src/input/backend/mousecontroller.cpp index 0dcfab6a2..f5db6780e 100644 --- a/src/input/backend/mousecontroller.cpp +++ b/src/input/backend/mousecontroller.cpp @@ -140,8 +140,9 @@ void MouseController::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) } } -MouseControllerFunctor::MouseControllerFunctor(InputHandler *handler) - : m_handler(handler) +MouseControllerFunctor::MouseControllerFunctor(QInputAspect *inputAspect, InputHandler *handler) + : m_inputAspect(inputAspect) + , m_handler(handler) { } @@ -149,6 +150,7 @@ Qt3DCore::QBackendNode *MouseControllerFunctor::create(Qt3DCore::QNode *frontend { MouseController *controller = m_handler->mouseControllerManager()->getOrCreateResource(frontend->id()); controller->setFactory(factory); + controller->setInputAspect(m_inputAspect); controller->setInputHandler(m_handler); controller->setPeer(frontend); m_handler->appendMouseController(m_handler->mouseControllerManager()->lookupHandle(frontend->id())); diff --git a/src/input/backend/mousecontroller_p.h b/src/input/backend/mousecontroller_p.h index 35ecf7da2..b1aa7185a 100644 --- a/src/input/backend/mousecontroller_p.h +++ b/src/input/backend/mousecontroller_p.h @@ -54,6 +54,9 @@ QT_BEGIN_NAMESPACE namespace Qt3DInput { + +class QInputAspect; + namespace Input { class InputHandler; @@ -109,13 +112,14 @@ private: class MouseControllerFunctor : public Qt3DCore::QBackendNodeFunctor { public: - explicit MouseControllerFunctor(InputHandler *handler); + explicit MouseControllerFunctor(Qt3DInput::QInputAspect *inputAspect, InputHandler *handler); Qt3DCore::QBackendNode *create(Qt3DCore::QNode *frontend, const Qt3DCore::QBackendNodeFactory *factory) const Q_DECL_OVERRIDE; Qt3DCore::QBackendNode *get(const Qt3DCore::QNodeId &id) const Q_DECL_OVERRIDE; void destroy(const Qt3DCore::QNodeId &id) const Q_DECL_OVERRIDE; private: + QInputAspect *m_inputAspect; InputHandler *m_handler; }; diff --git a/src/input/backend/qabstractphysicaldevicebackendnode.cpp b/src/input/backend/qabstractphysicaldevicebackendnode.cpp index 9803c575b..f1a668282 100644 --- a/src/input/backend/qabstractphysicaldevicebackendnode.cpp +++ b/src/input/backend/qabstractphysicaldevicebackendnode.cpp @@ -38,32 +38,104 @@ #include "qabstractphysicaldevicebackendnode_p.h" #include "qabstractphysicaldevice.h" #include "qaxissetting.h" +#include "inputhandler_p.h" +#include "inputmanagers_p.h" + +#include <Qt3DInput/qinputaspect.h> +#include <Qt3DInput/private/qinputaspect_p.h> #include <Qt3DCore/qscenepropertychange.h> +#include <Qt3DCore/private/qabstractaspect_p.h> + +#include <cmath> QT_BEGIN_NAMESPACE +namespace { + +QVector<int> variantListToVector(const QVariantList &list) +{ + QVector<int> v(list.size()); + int i = 0; + Q_FOREACH (const QVariant &e, list) { + v[i++] = e.toInt(); + } + return v; +} + +} + namespace Qt3DInput { QAbstractPhysicalDeviceBackendNodePrivate::QAbstractPhysicalDeviceBackendNodePrivate(Qt3DCore::QBackendNode::Mode mode) : Qt3DCore::QBackendNodePrivate(mode) , m_axisSettings() + , m_inputAspect(Q_NULLPTR) , m_enabled(false) { } +void QAbstractPhysicalDeviceBackendNodePrivate::addAxisSetting(int axisIdentifier, Qt3DCore::QNodeId axisSettingsId) +{ + Input::AxisIdSetting axisIdSetting; + axisIdSetting.m_axisIdentifier = axisIdentifier; + axisIdSetting.m_axisSettingsId = axisSettingsId; + + // Replace if already present, otherwise append + bool replaced = false; + QVector<Input::AxisIdSetting>::iterator it; + QVector<Input::AxisIdSetting>::iterator end = m_axisSettings.end(); + for (it = m_axisSettings.begin(); it != end; ++it) { + if (it->m_axisIdentifier == axisIdentifier) { + *it = axisIdSetting; + replaced = true; + break; + } + } + + if (!replaced) + m_axisSettings.push_back(axisIdSetting); +} + +void QAbstractPhysicalDeviceBackendNodePrivate::removeAxisSetting(Qt3DCore::QNodeId axisSettingsId) +{ + QVector<Input::AxisIdSetting>::iterator it; + for (it = m_axisSettings.begin(); it != m_axisSettings.end(); ++it) { + if (it->m_axisSettingsId == axisSettingsId) + m_axisSettings.erase(it); + } +} + +Input::AxisSetting *QAbstractPhysicalDeviceBackendNodePrivate::getAxisSetting(Qt3DCore::QNodeId axisSettingId) const +{ + Q_Q(const QAbstractPhysicalDeviceBackendNode); + QInputAspectPrivate *aspectPrivate = static_cast<QInputAspectPrivate *>(Qt3DCore::QAbstractAspectPrivate::get(q->inputAspect())); + Input::InputHandler *handler = aspectPrivate->m_inputHandler.data(); + Input::AxisSetting *axisSetting = handler->axisSettingManager()->getOrCreateResource(axisSettingId); + return axisSetting; +} + QAbstractPhysicalDeviceBackendNode::QAbstractPhysicalDeviceBackendNode(QBackendNode::Mode mode) : Qt3DCore::QBackendNode(*new QAbstractPhysicalDeviceBackendNodePrivate(mode)) { } +QAbstractPhysicalDeviceBackendNode::QAbstractPhysicalDeviceBackendNode(QAbstractPhysicalDeviceBackendNodePrivate &dd) + : Qt3DCore::QBackendNode(dd) +{ +} + void QAbstractPhysicalDeviceBackendNode::updateFromPeer(Qt3DCore::QNode *peer) { Q_D(QAbstractPhysicalDeviceBackendNode); QAbstractPhysicalDevice *physicalDevice = static_cast<QAbstractPhysicalDevice *>(peer); d->m_enabled = physicalDevice->isEnabled(); - Q_FOREACH (QAxisSetting *axisSetting, physicalDevice->axisSettings()) - d->m_axisSettings.push_back(axisSetting->id()); + Q_FOREACH (QAxisSetting *axisSetting, physicalDevice->axisSettings()) { + // Each axis setting can apply to more than one axis. If an axis is + // mentioned in more than one setting, we use the last one + Q_FOREACH (int axisId, variantListToVector(axisSetting->axes())) + d->addAxisSetting(axisId, axisSetting->id()); + } } void QAbstractPhysicalDeviceBackendNode::cleanup() @@ -71,6 +143,7 @@ void QAbstractPhysicalDeviceBackendNode::cleanup() Q_D(QAbstractPhysicalDeviceBackendNode); d->m_enabled = false; d->m_axisSettings.clear(); + d->m_inputAspect = Q_NULLPTR; } void QAbstractPhysicalDeviceBackendNode::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) @@ -82,17 +155,67 @@ void QAbstractPhysicalDeviceBackendNode::sceneChangeEvent(const Qt3DCore::QScene d->m_enabled = propertyChange->value().toBool(); } } else if (e->type() == Qt3DCore::NodeAdded) { - if (propertyChange->propertyName() == QByteArrayLiteral("axisSettings")) - d->m_axisSettings.push_back(propertyChange->value().value<Qt3DCore::QNodeId>()); + if (propertyChange->propertyName() == QByteArrayLiteral("axisSettings")) { + const Qt3DCore::QNodeId axisSettingId = propertyChange->value().value<Qt3DCore::QNodeId>(); + Input::AxisSetting *axisSetting = d->getAxisSetting(axisSettingId); + Q_FOREACH (int axisId, axisSetting->axes()) + d->addAxisSetting(axisId, axisSettingId); + } } else if (e->type() == Qt3DCore::NodeRemoved) { if (propertyChange->propertyName() == QByteArrayLiteral("axisSettings")) - d->m_axisSettings.removeOne(propertyChange->value().value<Qt3DCore::QNodeId>()); + d->removeAxisSetting(propertyChange->value().value<Qt3DCore::QNodeId>()); } } -QAbstractPhysicalDeviceBackendNode::QAbstractPhysicalDeviceBackendNode(QAbstractPhysicalDeviceBackendNodePrivate &dd) - : Qt3DCore::QBackendNode(dd) +void QAbstractPhysicalDeviceBackendNode::setInputAspect(QInputAspect *aspect) +{ + Q_D(QAbstractPhysicalDeviceBackendNode); + d->m_inputAspect = aspect; +} + +QInputAspect *QAbstractPhysicalDeviceBackendNode::inputAspect() const { + Q_D(const QAbstractPhysicalDeviceBackendNode); + Q_ASSERT_X(d->m_inputAspect, "QAbstractPhysicalDeviceBackendNode::inputAspect()" , "No input aspect set"); + return d->m_inputAspect; +} + +float QAbstractPhysicalDeviceBackendNode::processedAxisValue(int axisIdentifier) const +{ + // Find axis settings for this axis (if any) + Q_D(const QAbstractPhysicalDeviceBackendNode); + Qt3DCore::QNodeId axisSettingId; + QVector<Input::AxisIdSetting>::const_iterator it; + QVector<Input::AxisIdSetting>::const_iterator end = d->m_axisSettings.cend(); + for (it = d->m_axisSettings.cbegin(); it != end; ++it) { + if (it->m_axisIdentifier == axisIdentifier) { + axisSettingId = it->m_axisSettingsId; + break; + } + } + + const float rawAxisValue = axisValue(axisIdentifier); + if (axisSettingId.isNull()) { + // No special processing. Just return the raw value + return rawAxisValue; + } else { + // Process the raw value in accordance with the settings + Input::AxisSetting *axisSetting = d->getAxisSetting(axisSettingId); + Q_ASSERT(axisSetting); + float val = rawAxisValue; + + // Deadzone handling + if (!qFuzzyIsNull(axisSetting->deadZone())) { + if (std::abs(val) <= axisSetting->deadZone()) + val = 0.0f; + } + qDebug() << "Using axis settings. rawValue =" << rawAxisValue << "processedValue =" << val; + + // TODO: Low pass filtering + + return val; + } + } } // Qt3DInput diff --git a/src/input/backend/qabstractphysicaldevicebackendnode.h b/src/input/backend/qabstractphysicaldevicebackendnode.h index 777f2aba5..7555dec71 100644 --- a/src/input/backend/qabstractphysicaldevicebackendnode.h +++ b/src/input/backend/qabstractphysicaldevicebackendnode.h @@ -48,6 +48,7 @@ class QBackendNodePrivate; namespace Qt3DInput { +class QInputAspect; class QAbstractPhysicalDeviceBackendNodePrivate; class QT3DINPUTSHARED_EXPORT QAbstractPhysicalDeviceBackendNode : public Qt3DCore::QBackendNode @@ -58,6 +59,10 @@ public: void cleanup(); void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE; + void setInputAspect(QInputAspect *aspect); + QInputAspect *inputAspect() const; + + float processedAxisValue(int axisIdentifier) const; virtual float axisValue(int axisIdentifier) const = 0; virtual bool isButtonPressed(int buttonIdentifier) const = 0; diff --git a/src/input/backend/qabstractphysicaldevicebackendnode_p.h b/src/input/backend/qabstractphysicaldevicebackendnode_p.h index dfd7605a1..eac9a2255 100644 --- a/src/input/backend/qabstractphysicaldevicebackendnode_p.h +++ b/src/input/backend/qabstractphysicaldevicebackendnode_p.h @@ -57,12 +57,35 @@ QT_BEGIN_NAMESPACE namespace Qt3DInput { +class QAxisSetting; +class QInputAspect; + +namespace Input { + +struct AxisIdSetting +{ + int m_axisIdentifier; + Qt3DCore::QNodeId m_axisSettingsId; +}; + +class AxisSetting; + +} + class QT3DINPUTSHARED_PRIVATE_EXPORT QAbstractPhysicalDeviceBackendNodePrivate : public Qt3DCore::QBackendNodePrivate { public: explicit QAbstractPhysicalDeviceBackendNodePrivate(Qt3DCore::QBackendNode::Mode mode = Qt3DCore::QBackendNode::ReadOnly); - QVector<Qt3DCore::QNodeId> m_axisSettings; + Q_DECLARE_PUBLIC(QAbstractPhysicalDeviceBackendNode) + + void addAxisSetting(int axisIdentifier, Qt3DCore::QNodeId axisSettingId); + void removeAxisSetting(Qt3DCore::QNodeId axisSettingsId); + + Input::AxisSetting *getAxisSetting(Qt3DCore::QNodeId axisSettingId) const; + + QVector<Input::AxisIdSetting> m_axisSettings; + QInputAspect *m_inputAspect; bool m_enabled; }; diff --git a/src/input/backend/updateaxisactionjob.cpp b/src/input/backend/updateaxisactionjob.cpp index 5c2a336dc..406aa952c 100644 --- a/src/input/backend/updateaxisactionjob.cpp +++ b/src/input/backend/updateaxisactionjob.cpp @@ -122,7 +122,7 @@ void UpdateAxisActionJob::updateAxis(LogicalDevice *device) const QVector<int> keys = axisInput->keys(); // Axis was specified -> we take this as the base value if (axisInput->axis() != -1) - axisValue += physicalDeviceBackend->axisValue(axisInput->axis()); + axisValue += physicalDeviceBackend->processedAxisValue(axisInput->axis()); else if (!keys.isEmpty()) { // TO DO: Linear Curver for the progression of the scale value if (anyOfRequiredKeysPressed(keys, physicalDeviceBackend)) diff --git a/src/input/frontend/qinputaspect.cpp b/src/input/frontend/qinputaspect.cpp index 1f8d71872..681b9a0de 100644 --- a/src/input/frontend/qinputaspect.cpp +++ b/src/input/frontend/qinputaspect.cpp @@ -103,9 +103,9 @@ QInputAspectPrivate::QInputAspectPrivate() QInputAspect::QInputAspect(QObject *parent) : QAbstractAspect(*new QInputAspectPrivate, parent) { - registerBackendType<QKeyboardController>(QBackendNodeFunctorPtr(new Input::KeyboardControllerFunctor(d_func()->m_inputHandler.data()))); + registerBackendType<QKeyboardController>(QBackendNodeFunctorPtr(new Input::KeyboardControllerFunctor(this, d_func()->m_inputHandler.data()))); registerBackendType<QKeyboardInput>(QBackendNodeFunctorPtr(new Input::KeyboardInputFunctor(d_func()->m_inputHandler.data()))); - registerBackendType<QMouseController>(QBackendNodeFunctorPtr(new Input::MouseControllerFunctor(d_func()->m_inputHandler.data()))); + registerBackendType<QMouseController>(QBackendNodeFunctorPtr(new Input::MouseControllerFunctor(this, d_func()->m_inputHandler.data()))); registerBackendType<QMouseInput>(QBackendNodeFunctorPtr(new Input::MouseInputFunctor(d_func()->m_inputHandler.data()))); registerBackendType<QAxis>(QBackendNodeFunctorPtr(new Input::InputNodeFunctor<Input::Axis, Input::AxisManager>(d_func()->m_inputHandler->axisManager()))); registerBackendType<QAxisInput>(QBackendNodeFunctorPtr(new Input::InputNodeFunctor<Input::AxisInput, Input::AxisInputManager>(d_func()->m_inputHandler->axisInputManager()))); |