summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Harmer <sean.harmer@kdab.com>2016-11-25 12:09:51 +0000
committerJani Heikkinen <jani.heikkinen@qt.io>2016-12-07 05:53:54 +0000
commit22f6718ec4da3851de913d2de18dc0375574a458 (patch)
tree090c6d0c4baeabc91b16ddc2a721e1e4e8577a61
parent073664d6d7cc5b2081c32c4a75b7a6d8030de859 (diff)
Add plumbing and process AxisAccumulators each frame
Change-Id: I91a0f9384c7ef2ba642db1a2becdba1d2e374d87 Reviewed-by: Kevin Ottens <kevin.ottens@kdab.com>
-rw-r--r--src/input/backend/axisaccumulator.cpp42
-rw-r--r--src/input/backend/axisaccumulator_p.h8
-rw-r--r--src/input/backend/axisaccumulatorjob.cpp73
-rw-r--r--src/input/backend/axisaccumulatorjob_p.h89
-rw-r--r--src/input/backend/backend.pri6
-rw-r--r--src/input/backend/handle_types_p.h2
-rw-r--r--src/input/backend/inputhandler.cpp2
-rw-r--r--src/input/backend/inputhandler_p.h3
-rw-r--r--src/input/backend/inputmanagers_p.h11
-rw-r--r--src/input/backend/job_common_p.h3
-rw-r--r--src/input/frontend/qaxisaccumulator.cpp32
-rw-r--r--src/input/frontend/qaxisaccumulator.h3
-rw-r--r--src/input/frontend/qaxisaccumulator_p.h2
-rw-r--r--src/input/frontend/qinputaspect.cpp21
-rw-r--r--src/input/frontend/qinputaspect_p.h1
-rw-r--r--tests/auto/input/axisaccumulator/tst_axisaccumulator.cpp110
-rw-r--r--tests/auto/input/axisaccumulatorjob/axisaccumulatorjob.pro11
-rw-r--r--tests/auto/input/axisaccumulatorjob/tst_axisaccumulatorjob.cpp101
-rw-r--r--tests/auto/input/input.pro3
-rw-r--r--tests/auto/input/qaxisaccumulator/tst_qaxisaccumulator.cpp11
20 files changed, 529 insertions, 5 deletions
diff --git a/src/input/backend/axisaccumulator.cpp b/src/input/backend/axisaccumulator.cpp
index 4843f35f3..3b0423f47 100644
--- a/src/input/backend/axisaccumulator.cpp
+++ b/src/input/backend/axisaccumulator.cpp
@@ -39,6 +39,7 @@
#include "axisaccumulator_p.h"
#include <Qt3DInput/private/qaxisaccumulator_p.h>
+#include <Qt3DInput/private/inputmanagers_p.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
QT_BEGIN_NAMESPACE
@@ -52,6 +53,7 @@ AxisAccumulator::AxisAccumulator()
, m_sourceAxisType(QAxisAccumulator::Velocity)
, m_scale(1.0f)
, m_value(0.0f)
+ , m_velocity(0.0f)
{
}
@@ -62,6 +64,8 @@ void AxisAccumulator::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBaseP
m_sourceAxisId = data.sourceAxisId;
m_sourceAxisType = data.sourceAxisType;
m_scale = data.scale;
+ m_value = 0.0f;
+ m_velocity = 0.0f;
}
void AxisAccumulator::cleanup()
@@ -87,6 +91,20 @@ void AxisAccumulator::setValue(float value)
}
}
+void AxisAccumulator::setVelocity(float velocity)
+{
+ if (isEnabled() && velocity != m_velocity) {
+ m_velocity = velocity;
+
+ // Send a change to the frontend
+ auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
+ e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
+ e->setPropertyName("velocity");
+ e->setValue(m_velocity);
+ notifyObservers(e);
+ }
+}
+
void AxisAccumulator::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
{
switch (e->type()) {
@@ -107,6 +125,30 @@ void AxisAccumulator::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
QBackendNode::sceneChangeEvent(e);
}
+void AxisAccumulator::stepIntegration(AxisManager *axisManager, float dt)
+{
+ Axis *sourceAxis = axisManager->lookupResource(m_sourceAxisId);
+ if (!sourceAxis)
+ return;
+
+ const float axisValue = sourceAxis->axisValue();
+ float newVelocity = 0.0f;
+ float newValue = 0.0f;
+ switch (m_sourceAxisType) {
+ case QAxisAccumulator::Velocity:
+ newVelocity = axisValue * m_scale;
+ newValue = m_value + newVelocity * dt;
+ break;
+
+ case QAxisAccumulator::Acceleration:
+ newVelocity = m_velocity + axisValue * m_scale * dt;
+ newValue = m_value + newVelocity * dt;
+ break;
+ }
+ setVelocity(newVelocity);
+ setValue(newValue);
+}
+
} // namespace Input
} // namespace Qt3DInput
diff --git a/src/input/backend/axisaccumulator_p.h b/src/input/backend/axisaccumulator_p.h
index 8ddc9951b..67eb3906a 100644
--- a/src/input/backend/axisaccumulator_p.h
+++ b/src/input/backend/axisaccumulator_p.h
@@ -61,6 +61,8 @@ QT_BEGIN_NAMESPACE
namespace Qt3DInput {
namespace Input {
+class AxisManager;
+
class Q_AUTOTEST_EXPORT AxisAccumulator : public Qt3DCore::QBackendNode
{
public:
@@ -74,8 +76,13 @@ public:
float value() const Q_DECL_NOTHROW { return m_value; }
void setValue(float value);
+ float velocity() const Q_DECL_NOTHROW { return m_velocity; }
+ void setVelocity(float velocity);
+
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE;
+ void stepIntegration(AxisManager *axisManager, float dt);
+
private:
void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) Q_DECL_FINAL;
@@ -83,6 +90,7 @@ private:
QAxisAccumulator::SourceAxisType m_sourceAxisType;
float m_scale;
float m_value;
+ float m_velocity;
};
} // namespace Input
diff --git a/src/input/backend/axisaccumulatorjob.cpp b/src/input/backend/axisaccumulatorjob.cpp
new file mode 100644
index 000000000..133f9713a
--- /dev/null
+++ b/src/input/backend/axisaccumulatorjob.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** 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:LGPL$
+** 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.
+**
+** 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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "axisaccumulatorjob_p.h"
+#include <Qt3DInput/private/axisaccumulator_p.h>
+#include <Qt3DInput/private/job_common_p.h>
+#include <Qt3DInput/private/inputmanagers_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DInput {
+namespace Input {
+
+AxisAccumulatorJob::AxisAccumulatorJob(AxisAccumulatorManager *axisAccumulatormanager,
+ AxisManager *axisManager)
+ : Qt3DCore::QAspectJob()
+ , m_axisAccumulatorManager(axisAccumulatormanager)
+ , m_axisManager(axisManager)
+ , m_dt(0.0f)
+{
+ SET_JOB_RUN_STAT_TYPE(this, JobTypes::AxisAccumulatorIntegration, 0);
+}
+
+void AxisAccumulatorJob::run()
+{
+ // Iterate over the accumulators and ask each to step the integrations
+ for (auto accumulatorHandle : m_axisAccumulatorManager->activeHandles()) {
+ AxisAccumulator *accumulator = m_axisAccumulatorManager->data(accumulatorHandle);
+ if (accumulator->isEnabled())
+ accumulator->stepIntegration(m_axisManager, m_dt);
+ }
+}
+
+} // namespace Input
+} // namespace Qt3DInput
+
+QT_END_NAMESPACE
diff --git a/src/input/backend/axisaccumulatorjob_p.h b/src/input/backend/axisaccumulatorjob_p.h
new file mode 100644
index 000000000..d8ced8a3a
--- /dev/null
+++ b/src/input/backend/axisaccumulatorjob_p.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** 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:LGPL$
+** 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.
+**
+** 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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DINPUT_INPUT_AXISACCUMULATORJOB_H
+#define QT3DINPUT_INPUT_AXISACCUMULATORJOB_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 <Qt3DCore/qaspectjob.h>
+#include <Qt3DCore/qnodeid.h>
+#include <Qt3DInput/private/handle_types_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DInput {
+namespace Input {
+
+class AxisAccumulatorManager;
+class AxisManager;
+
+class Q_AUTOTEST_EXPORT AxisAccumulatorJob : public Qt3DCore::QAspectJob
+{
+public:
+ AxisAccumulatorJob(AxisAccumulatorManager *axisAccumulatormanager,
+ AxisManager *axisManager);
+
+ void setDeltaTime(float dt) { m_dt = dt; }
+
+ void run() override;
+
+private:
+ AxisAccumulatorManager *m_axisAccumulatorManager;
+ AxisManager *m_axisManager;
+ float m_dt;
+};
+
+typedef QSharedPointer<AxisAccumulatorJob> AxisAccumulatorJobPtr;
+
+} // namespace Input
+} // namespace Qt3DInput
+
+QT_END_NAMESPACE
+
+#endif // QT3DINPUT_INPUT_AXISACCUMULATORJOB_H
diff --git a/src/input/backend/backend.pri b/src/input/backend/backend.pri
index a0f6df9f0..71c1a9a1c 100644
--- a/src/input/backend/backend.pri
+++ b/src/input/backend/backend.pri
@@ -35,7 +35,8 @@ HEADERS += \
$$PWD/physicaldeviceproxy_p.h \
$$PWD/loadproxydevicejob_p.h \
$$PWD/utils_p.h \
- $$PWD/axisaccumulator_p.h
+ $$PWD/axisaccumulator_p.h \
+ $$PWD/axisaccumulatorjob_p.h
SOURCES += \
$$PWD/keyboarddevice.cpp \
@@ -68,6 +69,7 @@ SOURCES += \
$$PWD/eventsourcesetterhelper.cpp \
$$PWD/physicaldeviceproxy.cpp \
$$PWD/loadproxydevicejob.cpp \
- $$PWD/axisaccumulator.cpp
+ $$PWD/axisaccumulator.cpp \
+ $$PWD/axisaccumulatorjob.cpp
INCLUDEPATH += $$PWD
diff --git a/src/input/backend/handle_types_p.h b/src/input/backend/handle_types_p.h
index cc78a68ba..c132fdc99 100644
--- a/src/input/backend/handle_types_p.h
+++ b/src/input/backend/handle_types_p.h
@@ -73,6 +73,7 @@ class InputChord;
class LogicalDevice;
class GenericDeviceBackendNode;
class PhysicalDeviceProxy;
+class AxisAccumulator;
typedef Qt3DCore::QHandle<KeyboardDevice, 8> HKeyboardDevice;
typedef Qt3DCore::QHandle<KeyboardHandler, 16> HKeyboardHandler;
@@ -89,6 +90,7 @@ typedef Qt3DCore::QHandle<InputChord, 16> HInputChord;
typedef Qt3DCore::QHandle<LogicalDevice, 16> HLogicalDevice;
typedef Qt3DCore::QHandle<GenericDeviceBackendNode, 8> HGenericDeviceBackendNode;
typedef Qt3DCore::QHandle<PhysicalDeviceProxy, 16> HPhysicalDeviceProxy;
+typedef Qt3DCore::QHandle<AxisAccumulator, 16> HAxisAccumulator;
} // namespace Input
} // namespace Qt3DInput
diff --git a/src/input/backend/inputhandler.cpp b/src/input/backend/inputhandler.cpp
index 82b5c7c7c..aebf2c8f1 100644
--- a/src/input/backend/inputhandler.cpp
+++ b/src/input/backend/inputhandler.cpp
@@ -64,6 +64,7 @@ InputHandler::InputHandler()
, m_keyboardEventFilter(new KeyboardEventFilter())
, m_mouseEventFilter(new MouseEventFilter())
, m_axisManager(new AxisManager())
+ , m_axisAccumulatorManager(new AxisAccumulatorManager())
, m_actionManager(new ActionManager())
, m_axisSettingManager(new AxisSettingManager())
, m_actionInputManager(new ActionInputManager())
@@ -93,6 +94,7 @@ InputHandler::~InputHandler()
delete m_keyboardEventFilter;
delete m_mouseEventFilter;
delete m_axisManager;
+ delete m_axisAccumulatorManager;
delete m_actionManager;
delete m_axisSettingManager;
delete m_analogAxisInputManager;
diff --git a/src/input/backend/inputhandler_p.h b/src/input/backend/inputhandler_p.h
index 1628f3975..eff0c0c24 100644
--- a/src/input/backend/inputhandler_p.h
+++ b/src/input/backend/inputhandler_p.h
@@ -79,6 +79,7 @@ class MouseDeviceManager;
class MouseInputManager;
class MouseEventFilter;
class AxisManager;
+class AxisAccumulatorManager;
class ActionManager;
class AxisSettingManager;
class ActionInputManager;
@@ -104,6 +105,7 @@ public:
inline MouseDeviceManager *mouseDeviceManager() const { return m_mouseDeviceManager; }
inline MouseInputManager *mouseInputManager() const { return m_mouseInputManager; }
inline AxisManager *axisManager() const { return m_axisManager; }
+ inline AxisAccumulatorManager *axisAccumulatorManager() const { return m_axisAccumulatorManager; }
inline ActionManager *actionManager() const { return m_actionManager; }
inline AxisSettingManager *axisSettingManager() const { return m_axisSettingManager; }
inline ActionInputManager *actionInputManager() const { return m_actionInputManager; }
@@ -171,6 +173,7 @@ private:
mutable QMutex m_mutex;
AxisManager *m_axisManager;
+ AxisAccumulatorManager *m_axisAccumulatorManager;
ActionManager *m_actionManager;
AxisSettingManager *m_axisSettingManager;
ActionInputManager *m_actionInputManager;
diff --git a/src/input/backend/inputmanagers_p.h b/src/input/backend/inputmanagers_p.h
index d162ea519..473042867 100644
--- a/src/input/backend/inputmanagers_p.h
+++ b/src/input/backend/inputmanagers_p.h
@@ -63,6 +63,7 @@
#include <Qt3DInput/private/inputchord_p.h>
#include <Qt3DInput/private/action_p.h>
#include <Qt3DInput/private/axis_p.h>
+#include <Qt3DInput/private/axisaccumulator_p.h>
#include <Qt3DInput/private/axissetting_p.h>
#include <Qt3DInput/private/analogaxisinput_p.h>
#include <Qt3DInput/private/buttonaxisinput_p.h>
@@ -238,6 +239,16 @@ private:
QVector<Qt3DCore::QNodeId> m_pendingProxies;
};
+class AxisAccumulatorManager : public Qt3DCore::QResourceManager<
+ AxisAccumulator,
+ Qt3DCore::QNodeId,
+ 16,
+ Qt3DCore::ArrayAllocatingPolicy>
+{
+public:
+ AxisAccumulatorManager() {}
+};
+
} // namespace Input
} // namespace Qt3DInput
diff --git a/src/input/backend/job_common_p.h b/src/input/backend/job_common_p.h
index 589c75fb9..7377e4729 100644
--- a/src/input/backend/job_common_p.h
+++ b/src/input/backend/job_common_p.h
@@ -66,7 +66,8 @@ namespace JobTypes {
KeyEventDispatcher,
MouseEventDispatcher,
UpdateAxisAction,
- DeviceProxyLoading
+ DeviceProxyLoading,
+ AxisAccumulatorIntegration
};
} // JobTypes
diff --git a/src/input/frontend/qaxisaccumulator.cpp b/src/input/frontend/qaxisaccumulator.cpp
index 9a14c0deb..0785ad689 100644
--- a/src/input/frontend/qaxisaccumulator.cpp
+++ b/src/input/frontend/qaxisaccumulator.cpp
@@ -108,6 +108,7 @@ QAxisAccumulatorPrivate::QAxisAccumulatorPrivate()
, m_sourceAxisType(QAxisAccumulator::Velocity)
, m_scale(1.0f)
, m_value(0.0f)
+ , m_velocity(0.0f)
{
}
@@ -115,8 +116,23 @@ QAxisAccumulatorPrivate::QAxisAccumulatorPrivate()
void QAxisAccumulatorPrivate::setValue(float value)
{
if (value != m_value) {
+ Q_Q(QAxisAccumulator);
m_value = value;
- q_func()->valueChanged(m_value);
+ const bool wasBlocked = q->blockNotifications(true);
+ q->valueChanged(m_value);
+ q->blockNotifications(wasBlocked);
+ }
+}
+
+/*! \internal */
+void QAxisAccumulatorPrivate::setVelocity(float velocity)
+{
+ if (velocity != m_velocity) {
+ Q_Q(QAxisAccumulator);
+ m_velocity = velocity;
+ const bool wasBlocked = q->blockNotifications(true);
+ q->velocityChanged(m_velocity);
+ q->blockNotifications(wasBlocked);
}
}
@@ -180,6 +196,18 @@ float QAxisAccumulator::value() const
}
/*!
+ Returns the velocity. If the sourceAxisType is set to Velocity this is
+ simply the value of the source axis multiplied by the scale. If the
+ sourceAxisType is set to Acceleration, the velocity is integrated using
+ the source axis' value as an acceleration.
+ */
+float QAxisAccumulator::velocity() const
+{
+ Q_D(const QAxisAccumulator);
+ return d->m_velocity;
+}
+
+/*!
\qmlproperty real Qt3D.Input::AxisAccumulator::value
The amount to scale the axis value by when accumulating. This can be
@@ -255,6 +283,8 @@ void QAxisAccumulator::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change)
auto e = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(change);
if (e->type() == Qt3DCore::PropertyUpdated && e->propertyName() == QByteArrayLiteral("value"))
d->setValue(e->value().toFloat());
+ else if (e->type() == Qt3DCore::PropertyUpdated && e->propertyName() == QByteArrayLiteral("velocity"))
+ d->setVelocity(e->value().toFloat());
}
/*! \internal */
diff --git a/src/input/frontend/qaxisaccumulator.h b/src/input/frontend/qaxisaccumulator.h
index 009b2531c..b31f57a48 100644
--- a/src/input/frontend/qaxisaccumulator.h
+++ b/src/input/frontend/qaxisaccumulator.h
@@ -57,6 +57,7 @@ class QT3DINPUTSHARED_EXPORT QAxisAccumulator : public Qt3DCore::QComponent
Q_PROPERTY(SourceAxisType sourceAxisType READ sourceAxisType WRITE setSourceAxisType NOTIFY sourceAxisTypeChanged)
Q_PROPERTY(float scale READ scale WRITE setScale NOTIFY scaleChanged)
Q_PROPERTY(float value READ value NOTIFY valueChanged)
+ Q_PROPERTY(float velocity READ velocity NOTIFY velocityChanged)
public:
enum SourceAxisType {
@@ -71,6 +72,7 @@ public:
Qt3DInput::QAxis *sourceAxis() const;
SourceAxisType sourceAxisType() const;
float value() const;
+ float velocity() const;
float scale() const;
public Q_SLOTS:
@@ -82,6 +84,7 @@ Q_SIGNALS:
void sourceAxisChanged(Qt3DInput::QAxis *sourceAxis);
void sourceAxisTypeChanged(QAxisAccumulator::SourceAxisType sourceAxisType);
void valueChanged(float value);
+ void velocityChanged(float value);
void scaleChanged(float scale);
protected:
diff --git a/src/input/frontend/qaxisaccumulator_p.h b/src/input/frontend/qaxisaccumulator_p.h
index be0410c5c..532f01b6b 100644
--- a/src/input/frontend/qaxisaccumulator_p.h
+++ b/src/input/frontend/qaxisaccumulator_p.h
@@ -66,11 +66,13 @@ public:
Q_DECLARE_PUBLIC(QAxisAccumulator)
void setValue(float value);
+ void setVelocity(float velocity);
QAxis *m_sourceAxis;
QAxisAccumulator::SourceAxisType m_sourceAxisType;
float m_scale;
float m_value;
+ float m_velocity;
};
struct QAxisAccumulatorData
diff --git a/src/input/frontend/qinputaspect.cpp b/src/input/frontend/qinputaspect.cpp
index 5ad5c644c..066d2381a 100644
--- a/src/input/frontend/qinputaspect.cpp
+++ b/src/input/frontend/qinputaspect.cpp
@@ -61,6 +61,7 @@
#include <QPluginLoader>
#include <Qt3DInput/qaxis.h>
+#include <Qt3DInput/qaxisaccumulator.h>
#include <Qt3DInput/qaction.h>
#include <Qt3DInput/qaxissetting.h>
#include <Qt3DInput/qactioninput.h>
@@ -72,6 +73,7 @@
#include <Qt3DInput/qabstractphysicaldevice.h>
#include <Qt3DInput/private/qabstractphysicaldeviceproxy_p.h>
#include <Qt3DInput/private/axis_p.h>
+#include <Qt3DInput/private/axisaccumulator_p.h>
#include <Qt3DInput/private/action_p.h>
#include <Qt3DInput/private/axissetting_p.h>
#include <Qt3DInput/private/actioninput_p.h>
@@ -86,6 +88,7 @@
#include <Qt3DInput/private/inputsettings_p.h>
#include <Qt3DInput/private/eventsourcesetterhelper_p.h>
#include <Qt3DInput/private/loadproxydevicejob_p.h>
+#include <Qt3DInput/private/axisaccumulatorjob_p.h>
#ifdef HAVE_QGAMEPAD
# include <Qt3DInput/private/qgamepadinput_p.h>
@@ -101,6 +104,7 @@ QInputAspectPrivate::QInputAspectPrivate()
: QAbstractAspectPrivate()
, m_inputHandler(new Input::InputHandler())
, m_keyboardMouseIntegration(new Input::KeyboardMouseGenericDeviceIntegration(m_inputHandler.data()))
+ , m_time(0)
{
}
@@ -134,6 +138,7 @@ QInputAspect::QInputAspect(QInputAspectPrivate &dd, QObject *parent)
registerBackendType<QMouseDevice>(QBackendNodeMapperPtr(new Input::MouseDeviceFunctor(this, d_func()->m_inputHandler.data())));
registerBackendType<QMouseHandler>(QBackendNodeMapperPtr(new Input::MouseHandlerFunctor(d_func()->m_inputHandler.data())));
registerBackendType<QAxis>(QBackendNodeMapperPtr(new Input::InputNodeFunctor<Input::Axis, Input::AxisManager>(d_func()->m_inputHandler->axisManager())));
+ registerBackendType<QAxisAccumulator>(QBackendNodeMapperPtr(new Input::InputNodeFunctor<Input::AxisAccumulator, Input::AxisAccumulatorManager>(d_func()->m_inputHandler->axisAccumulatorManager())));
registerBackendType<QAnalogAxisInput>(QBackendNodeMapperPtr(new Input::InputNodeFunctor<Input::AnalogAxisInput, Input::AnalogAxisInputManager>(d_func()->m_inputHandler->analogAxisInputManager())));
registerBackendType<QButtonAxisInput>(QBackendNodeMapperPtr(new Input::InputNodeFunctor<Input::ButtonAxisInput, Input::ButtonAxisInputManager>(d_func()->m_inputHandler->buttonAxisInputManager())));
registerBackendType<QAxisSetting>(QBackendNodeMapperPtr(new Input::InputNodeFunctor<Input::AxisSetting, Input::AxisSettingManager>(d_func()->m_inputHandler->axisSettingManager())));
@@ -213,6 +218,10 @@ QStringList QInputAspect::availablePhysicalDevices() const
QVector<QAspectJobPtr> QInputAspect::jobsToExecute(qint64 time)
{
Q_D(QInputAspect);
+ const qint64 deltaTime = time - d->m_time;
+ const float dt = static_cast<const float>(deltaTime) / 1.0e9;
+ d->m_time = time;
+
QVector<QAspectJobPtr> jobs;
d->m_inputHandler->updateEventSource();
@@ -240,6 +249,8 @@ QVector<QAspectJobPtr> QInputAspect::jobsToExecute(qint64 time)
// Jobs that update Axis/Action (store combined axis/action value)
const auto devHandles = d->m_inputHandler->logicalDeviceManager()->activeDevices();
+ QVector<QAspectJobPtr> axisActionJobs;
+ axisActionJobs.reserve(devHandles.size());
for (Input::HLogicalDevice devHandle : devHandles) {
const auto device = d->m_inputHandler->logicalDeviceManager()->data(devHandle);
if (!device->isEnabled())
@@ -247,10 +258,20 @@ QVector<QAspectJobPtr> QInputAspect::jobsToExecute(qint64 time)
QAspectJobPtr updateAxisActionJob(new Input::UpdateAxisActionJob(time, d->m_inputHandler.data(), devHandle));
jobs += updateAxisActionJob;
+ axisActionJobs.push_back(updateAxisActionJob);
for (const QAspectJobPtr &job : dependsOnJobs)
updateAxisActionJob->addDependency(job);
}
+ // Once all the axes have been updated we can step the integrations on
+ // the AxisAccumulators
+ auto accumulateJob = Input::AxisAccumulatorJobPtr::create(d->m_inputHandler->axisAccumulatorManager(),
+ d->m_inputHandler->axisManager());
+ accumulateJob->setDeltaTime(dt);
+ for (const QAspectJobPtr &job : qAsConst(axisActionJobs))
+ accumulateJob->addDependency(job);
+ jobs.push_back(accumulateJob);
+
return jobs;
}
diff --git a/src/input/frontend/qinputaspect_p.h b/src/input/frontend/qinputaspect_p.h
index d123e6216..35a4ffa02 100644
--- a/src/input/frontend/qinputaspect_p.h
+++ b/src/input/frontend/qinputaspect_p.h
@@ -73,6 +73,7 @@ public:
Q_DECLARE_PUBLIC(QInputAspect)
QScopedPointer<Input::InputHandler> m_inputHandler;
QScopedPointer<Input::KeyboardMouseGenericDeviceIntegration> m_keyboardMouseIntegration;
+ qint64 m_time;
};
} // namespace Qt3DInput
diff --git a/tests/auto/input/axisaccumulator/tst_axisaccumulator.cpp b/tests/auto/input/axisaccumulator/tst_axisaccumulator.cpp
index a1c769aaa..94cb71030 100644
--- a/tests/auto/input/axisaccumulator/tst_axisaccumulator.cpp
+++ b/tests/auto/input/axisaccumulator/tst_axisaccumulator.cpp
@@ -36,6 +36,7 @@
#include <Qt3DInput/private/axis_p.h>
#include <Qt3DInput/private/axisaccumulator_p.h>
#include <Qt3DInput/private/qabstractaxisinput_p.h>
+#include <Qt3DInput/private/inputmanagers_p.h>
#include <Qt3DInput/QAnalogAxisInput>
#include <Qt3DInput/QAxis>
#include <Qt3DInput/QAxisAccumulator>
@@ -79,6 +80,7 @@ private Q_SLOTS:
QVERIFY(backendAxisAccumulator.peerId().isNull());
QCOMPARE(backendAxisAccumulator.isEnabled(), false);
QCOMPARE(backendAxisAccumulator.value(), 0.0f);
+ QCOMPARE(backendAxisAccumulator.velocity(), 0.0f);
QCOMPARE(backendAxisAccumulator.scale(), 1.0f);
QCOMPARE(backendAxisAccumulator.sourceAxisId(), Qt3DCore::QNodeId());
QCOMPARE(backendAxisAccumulator.sourceAxisType(), Qt3DInput::QAxisAccumulator::Velocity);
@@ -99,6 +101,7 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendAxisAccumulator.isEnabled(), false);
QCOMPARE(backendAxisAccumulator.value(), 0.0f);
+ QCOMPARE(backendAxisAccumulator.velocity(), 0.0f);
QCOMPARE(backendAxisAccumulator.scale(), 1.0f);
QCOMPARE(backendAxisAccumulator.sourceAxisId(), Qt3DCore::QNodeId());
QCOMPARE(backendAxisAccumulator.sourceAxisType(), Qt3DInput::QAxisAccumulator::Velocity);
@@ -177,6 +180,28 @@ private Q_SLOTS:
QCOMPARE(arbiter.events.count(), 0);
arbiter.events.clear();
+
+
+ // WHEN
+ backendAxisAccumulator.setVelocity(383.0f);
+
+ // THEN
+ QCOMPARE(backendAxisAccumulator.velocity(), 383.0f);
+ QCOMPARE(arbiter.events.count(), 1);
+ Qt3DCore::QPropertyUpdatedChangePtr velocityChange = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(velocityChange->propertyName(), "velocity");
+ QCOMPARE(velocityChange->value().toFloat(), backendAxisAccumulator.velocity());
+
+ arbiter.events.clear();
+
+ // WHEN
+ backendAxisAccumulator.setVelocity(383.0f);
+
+ // THEN
+ QCOMPARE(backendAxisAccumulator.velocity(), 383.0f);
+ QCOMPARE(arbiter.events.count(), 0);
+
+ arbiter.events.clear();
}
void shouldNotChangeValueWhenDisabled()
@@ -194,6 +219,91 @@ private Q_SLOTS:
QCOMPARE(backendAxisAccumulator.value(), 0.0f);
QCOMPARE(arbiter.events.count(), 0);
}
+
+ void checkIntegration_data()
+ {
+ QTest::addColumn<Qt3DInput::QAxisAccumulator::SourceAxisType>("sourceAxisType");
+ QTest::addColumn<float>("axisValue");
+ QTest::addColumn<float>("scale");
+ QTest::addColumn<float>("dt");
+ QTest::addColumn<float>("valueResult");
+ QTest::addColumn<float>("velocityResult");
+
+ QTest::newRow("velocity=10, axis=1, dt=1") << Qt3DInput::QAxisAccumulator::Velocity
+ << 1.0f
+ << 10.0f
+ << 1.0f
+ << 10.0f
+ << 0.0f;
+
+ QTest::newRow("velocity=10, axis=1, dt=0.2") << Qt3DInput::QAxisAccumulator::Velocity
+ << 1.0f
+ << 10.0f
+ << 0.2f
+ << 2.0f
+ << 0.0f;
+
+ QTest::newRow("velocity=20, axis=1, dt=0.1") << Qt3DInput::QAxisAccumulator::Velocity
+ << 1.0f
+ << 20.0f
+ << 0.1f
+ << 2.0f
+ << 0.0f;
+
+ QTest::newRow("velocity=10, axis=0.5, dt=1") << Qt3DInput::QAxisAccumulator::Velocity
+ << 0.5f
+ << 10.0f
+ << 1.0f
+ << 5.0f
+ << 0.0f;
+
+ QTest::newRow("acceleration=10, axis=1, dt=1") << Qt3DInput::QAxisAccumulator::Acceleration
+ << 1.0f
+ << 10.0f
+ << 1.0f
+ << 10.0f
+ << 10.0f;
+ }
+
+ void checkIntegration()
+ {
+ // GIVEN
+ QFETCH(Qt3DInput::QAxisAccumulator::SourceAxisType, sourceAxisType);
+ QFETCH(float, axisValue);
+ QFETCH(float, scale);
+ QFETCH(float, dt);
+ QFETCH(float, valueResult);
+ QFETCH(float, velocityResult);
+
+ Qt3DInput::QAxis *axis = new Qt3DInput::QAxis;
+ Qt3DInput::Input::AxisManager axisManager;
+ Qt3DInput::Input::Axis *backendAxis = axisManager.getOrCreateResource(axis->id());
+ Qt3DInput::QAxisAccumulator axisAccumulator;
+ Qt3DInput::Input::AxisAccumulator backendAxisAccumulator;
+
+ // WHEN
+ backendAxis->setEnabled(true);
+ backendAxis->setAxisValue(axisValue);
+ axisAccumulator.setSourceAxis(axis);
+ axisAccumulator.setScale(scale);
+ axisAccumulator.setSourceAxisType(sourceAxisType);
+ axisAccumulator.setEnabled(true);
+ simulateInitialization(&axisAccumulator, &backendAxisAccumulator);
+
+ backendAxisAccumulator.stepIntegration(&axisManager, dt);
+
+ // THEN
+ switch (sourceAxisType) {
+ case Qt3DInput::QAxisAccumulator::Velocity:
+ QCOMPARE(backendAxisAccumulator.value(), valueResult);
+ break;
+
+ case Qt3DInput::QAxisAccumulator::Acceleration:
+ QCOMPARE(backendAxisAccumulator.velocity(), velocityResult);
+ QCOMPARE(backendAxisAccumulator.value(), valueResult);
+ break;
+ }
+ }
};
QTEST_APPLESS_MAIN(tst_AxisAccumulator)
diff --git a/tests/auto/input/axisaccumulatorjob/axisaccumulatorjob.pro b/tests/auto/input/axisaccumulatorjob/axisaccumulatorjob.pro
new file mode 100644
index 000000000..ad1a1a469
--- /dev/null
+++ b/tests/auto/input/axisaccumulatorjob/axisaccumulatorjob.pro
@@ -0,0 +1,11 @@
+TEMPLATE = app
+
+TARGET = tst_axisaccumulatorjob
+
+QT += core-private 3dcore 3dcore-private 3dinput 3dinput-private testlib
+
+CONFIG += testcase
+
+SOURCES += tst_axisaccumulatorjob.cpp
+
+include(../../core/common/common.pri)
diff --git a/tests/auto/input/axisaccumulatorjob/tst_axisaccumulatorjob.cpp b/tests/auto/input/axisaccumulatorjob/tst_axisaccumulatorjob.cpp
new file mode 100644
index 000000000..fa3bca3d2
--- /dev/null
+++ b/tests/auto/input/axisaccumulatorjob/tst_axisaccumulatorjob.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 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:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QTest>
+#include <qbackendnodetester.h>
+#include <Qt3DCore/private/qnode_p.h>
+#include <Qt3DCore/private/qscene_p.h>
+#include <Qt3DCore/qpropertyupdatedchange.h>
+#include <Qt3DCore/qpropertynodeaddedchange.h>
+#include <Qt3DCore/qpropertynoderemovedchange.h>
+#include <Qt3DInput/private/axis_p.h>
+#include <Qt3DInput/private/axisaccumulator_p.h>
+#include <Qt3DInput/private/axisaccumulatorjob_p.h>
+#include <Qt3DInput/private/qabstractaxisinput_p.h>
+#include <Qt3DInput/private/inputmanagers_p.h>
+#include <Qt3DInput/QAnalogAxisInput>
+#include <Qt3DInput/QAxis>
+#include <Qt3DInput/QAxisAccumulator>
+#include <Qt3DCore/private/qbackendnode_p.h>
+#include "testpostmanarbiter.h"
+
+class tst_AxisAccumulatorJob : public Qt3DCore::QBackendNodeTester
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void checkIntegration()
+ {
+ // GIVEN
+ const auto sourceAxisType = Qt3DInput::QAxisAccumulator::Velocity;
+ const float axisValue = 1.0f;
+ const float scale = 10.0f;
+ const float dt = 0.1f;
+ const float valueResultEnabled = 1.0f;
+ const float valueResultDisabled = 0.0f;
+
+ // Set up an axis
+ Qt3DInput::QAxis *axis = new Qt3DInput::QAxis;
+ Qt3DInput::Input::AxisManager axisManager;
+ Qt3DInput::Input::Axis *backendAxis = axisManager.getOrCreateResource(axis->id());
+ backendAxis->setEnabled(true);
+ backendAxis->setAxisValue(axisValue);
+
+ // Hook up a bunch of accumulators to this axis
+ Qt3DInput::Input::AxisAccumulatorManager axisAccumulatorManager;
+ QVector<Qt3DInput::Input::AxisAccumulator *> accumulators;
+ for (int i = 0; i < 10; ++i) {
+ auto axisAccumulator = new Qt3DInput::QAxisAccumulator;
+ Qt3DInput::Input::AxisAccumulator *backendAxisAccumulator
+ = axisAccumulatorManager.getOrCreateResource(axisAccumulator->id());
+ accumulators.push_back(backendAxisAccumulator);
+
+ axisAccumulator->setEnabled(i % 2 == 0); // Enable only even accumulators
+ axisAccumulator->setSourceAxis(axis);
+ axisAccumulator->setScale(scale);
+ axisAccumulator->setSourceAxisType(sourceAxisType);
+ simulateInitialization(axisAccumulator, backendAxisAccumulator);
+ }
+
+ // WHEN
+ Qt3DInput::Input::AxisAccumulatorJob job(&axisAccumulatorManager, &axisManager);
+ job.setDeltaTime(dt);
+ job.run();
+
+
+ // THEN
+ for (const auto accumulator : accumulators) {
+ QCOMPARE(accumulator->value(), accumulator->isEnabled() ? valueResultEnabled
+ : valueResultDisabled);
+ }
+ }
+};
+
+QTEST_APPLESS_MAIN(tst_AxisAccumulatorJob)
+
+#include "tst_axisaccumulatorjob.moc"
diff --git a/tests/auto/input/input.pro b/tests/auto/input/input.pro
index fdd7ed2f7..6169d3f7c 100644
--- a/tests/auto/input/input.pro
+++ b/tests/auto/input/input.pro
@@ -28,5 +28,6 @@ qtConfig(private_tests) {
qmousedevice \
mousedevice \
utils \
- axisaccumulator
+ axisaccumulator \
+ axisaccumulatorjob
}
diff --git a/tests/auto/input/qaxisaccumulator/tst_qaxisaccumulator.cpp b/tests/auto/input/qaxisaccumulator/tst_qaxisaccumulator.cpp
index a98cf09a9..3df09a67a 100644
--- a/tests/auto/input/qaxisaccumulator/tst_qaxisaccumulator.cpp
+++ b/tests/auto/input/qaxisaccumulator/tst_qaxisaccumulator.cpp
@@ -183,6 +183,17 @@ private Q_SLOTS:
// THEN
QCOMPARE(value(), 383.0f);
+ QCOMPARE(velocity(), 0.0f);
+
+ // WHEN
+ valueChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("velocity");
+ valueChange->setValue(123.0f);
+ sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(value(), 383.0f);
+ QCOMPARE(velocity(), 123.0f);
}
void checkAxisInputBookkeeping()