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 | |
13 | QT_BEGIN_NAMESPACE |
14 | |
15 | namespace Qt3DInput { |
16 | |
17 | namespace Input { |
18 | |
19 | ButtonAxisInput::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 | |
29 | void 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 | |
38 | void 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 | |
56 | void 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 | |
69 | namespace { |
70 | |
71 | bool 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 | |
85 | float 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 | |
110 | QT_END_NAMESPACE |
111 | |