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/backend/qabstractphysicaldevicebackendnode.cpp | |
parent | 4125d98dfa4abdd6533bb7203b7e36a51dc545aa (diff) |
Implement dead zone support
Change-Id: Icd5d31ba690484dc310de872be9df3ec9a520c63
Reviewed-by: Kevin Ottens <kevin.ottens@kdab.com>
Diffstat (limited to 'src/input/backend/qabstractphysicaldevicebackendnode.cpp')
-rw-r--r-- | src/input/backend/qabstractphysicaldevicebackendnode.cpp | 137 |
1 files changed, 130 insertions, 7 deletions
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 |