summaryrefslogtreecommitdiffstats
path: root/src/input
diff options
context:
space:
mode:
authorSean Harmer <sean.harmer@kdab.com>2015-12-08 09:51:29 +0000
committerSean Harmer <sean.harmer@kdab.com>2015-12-16 09:47:30 +0000
commitc16863075cc73485d7a66c93e4b8d9fefcaf5f63 (patch)
tree7b228ce9b444719220ad7faf1f7176b7692ed87c /src/input
parent4125d98dfa4abdd6533bb7203b7e36a51dc545aa (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.cpp6
-rw-r--r--src/input/backend/keyboardcontroller_p.h6
-rw-r--r--src/input/backend/mousecontroller.cpp6
-rw-r--r--src/input/backend/mousecontroller_p.h6
-rw-r--r--src/input/backend/qabstractphysicaldevicebackendnode.cpp137
-rw-r--r--src/input/backend/qabstractphysicaldevicebackendnode.h5
-rw-r--r--src/input/backend/qabstractphysicaldevicebackendnode_p.h25
-rw-r--r--src/input/backend/updateaxisactionjob.cpp2
-rw-r--r--src/input/frontend/qinputaspect.cpp4
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())));