1// Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "buttonaxisinput_p.h"
5
6#include <Qt3DInput/qbuttonaxisinput.h>
7#include <Qt3DInput/qabstractphysicaldevice.h>
8
9#include <Qt3DInput/private/qabstractphysicaldevicebackendnode_p.h>
10#include <Qt3DInput/private/qbuttonaxisinput_p.h>
11#include <Qt3DInput/private/utils_p.h>
12
13QT_BEGIN_NAMESPACE
14
15namespace Qt3DInput {
16
17namespace Input {
18
19ButtonAxisInput::ButtonAxisInput()
20 : AbstractAxisInput()
21 , m_scale(0.0f)
22 , m_acceleration(-1.0f)
23 , m_deceleration(-1.0f)
24 , m_speedRatio(0.0f)
25 , m_lastUpdateTime(0)
26{
27}
28
29void ButtonAxisInput::cleanup()
30{
31 m_scale = 0.0f;
32 m_buttons.clear();
33 m_acceleration = -1.0f;
34 m_deceleration = -1.0f;
35 AbstractAxisInput::cleanup();
36}
37
38void ButtonAxisInput::updateSpeedRatio(qint64 currentTime, ButtonAxisInput::UpdateType type)
39{
40 const float accel = (type == Accelerate) ? acceleration() : -deceleration();
41
42 // Was in nanoseconds, while acceleration will be in units per square seconds
43 const float delta = m_lastUpdateTime ? (currentTime - m_lastUpdateTime) / 1000000000.0f : 0.0f;
44 const float speedRatio = m_speedRatio + delta * accel;
45
46 // Clamp it
47 m_speedRatio = qMax(a: 0.0f, b: qMin(a: speedRatio, b: 1.0f));
48
49 // If we stopped, time to start over
50 if (type == Decelerate && m_speedRatio == 0.0f)
51 m_lastUpdateTime = 0;
52 else
53 m_lastUpdateTime = currentTime;
54}
55
56void ButtonAxisInput::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime)
57{
58 AbstractAxisInput::syncFromFrontEnd(frontEnd, firstTime);
59 const QButtonAxisInput *node = qobject_cast<const QButtonAxisInput *>(object: frontEnd);
60 if (!node)
61 return;
62
63 m_scale = node->scale();
64 m_buttons = node->buttons();
65 m_acceleration = node->acceleration();
66 m_deceleration = node->deceleration();
67}
68
69namespace {
70
71bool anyOfRequiredButtonsPressed(const QList<int> &buttons, QAbstractPhysicalDeviceBackendNode *physicalDeviceBackend)
72{
73 bool validButtonWasPressed = false;
74 for (int button : buttons) {
75 if (physicalDeviceBackend->isButtonPressed(buttonIdentifier: button)) {
76 validButtonWasPressed = true;
77 break;
78 }
79 }
80 return validButtonWasPressed;
81}
82
83} // anonymous
84
85float ButtonAxisInput::process(InputHandler *inputHandler, qint64 currentTime)
86{
87 if (!isEnabled())
88 return 0.0f;
89
90 if (m_buttons.isEmpty())
91 return 0.0f;
92
93 QAbstractPhysicalDeviceBackendNode *physicalDeviceBackend = Utils::physicalDeviceForInput(input: this, handler: inputHandler);
94 if (!physicalDeviceBackend)
95 return 0.0f;
96
97 // TO DO: Linear Curver for the progression of the scale value
98 if (anyOfRequiredButtonsPressed(buttons: m_buttons, physicalDeviceBackend))
99 updateSpeedRatio(currentTime, type: ButtonAxisInput::Accelerate);
100 else if (m_speedRatio != 0.0f)
101 updateSpeedRatio(currentTime, type: ButtonAxisInput::Decelerate);
102
103 return m_speedRatio * m_scale;
104}
105
106} // Input
107
108} // Qt3DInput
109
110QT_END_NAMESPACE
111

source code of qt3d/src/input/backend/buttonaxisinput.cpp