1/****************************************************************************
2**
3** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt3D module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qaxisaccumulator.h"
41#include "qaxisaccumulator_p.h"
42
43#include <Qt3DInput/qaxis.h>
44#include <Qt3DCore/qnodecreatedchange.h>
45
46QT_BEGIN_NAMESPACE
47
48namespace Qt3DInput {
49
50/*!
51 Constructs a new QAxisAccumulator instance with \a parent.
52 \class Qt3DInput::QAxisAccumulator
53 \inmodule Qt3DInput
54 \inherits Qt3DCore::QComponent
55 \brief QAxisAccumulator processes velocity or acceleration data from a QAxis.
56 \since 5.8
57
58 A Qt3DInput::QAxis reports the current position of an axis on an input
59 device. When the axis is returned to its neutral position the value of that
60 axis returns to 0. Often, it is required to have the input from an axis
61 control a variable in other ways, for example treating the value from the
62 Qt3DInput::QAxis as a velocity (first derivative with respect to time) or
63 as an acceleration (second derivative with respect to time). This can be
64 done with user code or with a Qt3DLogic::QFrameAction but those approached
65 are not ideal as they add more work to the main thread and are inherently
66 imperative. The Qt3DInput::QAxisAccumulator class allows for this common
67 task to be performed on the Qt 3D backend and be specified in a declarative
68 manner.
69*/
70
71/*!
72 \qmltype AxisAccumulator
73 \inqmlmodule Qt3D.Input
74 \instantiates Qt3DInput::QAxisAccumulator
75 \brief QML frontend for the Qt3DInput::QAxisAccumulator C++ class.
76 \since 5.8
77
78 An Axis reports the current position of an axis on an input device. When the
79 axis is returned to its neutral position the value of that axis returns to 0.
80 Often, it is required to have the input from an axis control a variable in
81 other ways, for example treating the value from the Axis as a velocity (first
82 derivative with respect to time) or as an acceleration (second derivative with
83 respect to time). This can be done with user code or with a FrameAction but
84 those approached are not ideal as they add more work to the main thread and
85 are inherently imperative. The AxisAccumulator class allows for this common
86 task to be performed on the Qt 3D backend and be specified in a declarative
87 manner.
88*/
89
90/*!
91 \qmlproperty int Qt3D.Input::Axis::value
92 \readonly
93
94 Holds the value accumulated from the sourceAxis.
95*/
96
97/*!
98 * \enum Qt3DInput::QAxisAccumulator::SourceAxisType
99 *
100 * \value Velocity
101 * \value Acceleration
102 */
103
104/*! \internal */
105QAxisAccumulatorPrivate::QAxisAccumulatorPrivate()
106 : Qt3DCore::QComponentPrivate()
107 , m_sourceAxis(nullptr)
108 , m_sourceAxisType(QAxisAccumulator::Velocity)
109 , m_scale(1.0f)
110 , m_value(0.0f)
111 , m_velocity(0.0f)
112{
113}
114
115/*! \internal */
116void QAxisAccumulatorPrivate::setValue(float value)
117{
118 if (value != m_value) {
119 Q_Q(QAxisAccumulator);
120 m_value = value;
121 const bool wasBlocked = q->blockNotifications(block: true);
122 emit q->valueChanged(value: m_value);
123 q->blockNotifications(block: wasBlocked);
124 }
125}
126
127/*! \internal */
128void QAxisAccumulatorPrivate::setVelocity(float velocity)
129{
130 if (velocity != m_velocity) {
131 Q_Q(QAxisAccumulator);
132 m_velocity = velocity;
133 const bool wasBlocked = q->blockNotifications(block: true);
134 emit q->velocityChanged(value: m_velocity);
135 q->blockNotifications(block: wasBlocked);
136 }
137}
138
139/*!
140 Constructs a new QAxisAccumulator instance with parent \a parent.
141 */
142QAxisAccumulator::QAxisAccumulator(Qt3DCore::QNode *parent)
143 : Qt3DCore::QComponent(*new QAxisAccumulatorPrivate, parent)
144{
145}
146
147/*! \internal */
148QAxisAccumulator::~QAxisAccumulator()
149{
150}
151
152/*!
153 \qmlproperty Axis Qt3D.Input::AxisAccumulator::sourceAxis
154
155 The Axis for which the accumulator should integrate axis values.
156 */
157
158/*!
159 \return QAxis for which the accumulator should integrate axis values.
160 */
161QAxis *QAxisAccumulator::sourceAxis() const
162{
163 Q_D(const QAxisAccumulator);
164 return d->m_sourceAxis;
165}
166
167/*!
168 \qmlproperty SourceAxisType Qt3D.Input::AxisAccumulator::sourceAxisType
169
170 The sourceAxisType property specifies how the accumulator treats the values
171 from the source axis.
172 */
173
174/*!
175 \return how the accumulator treats the value of the sourceAxis.
176 */
177QAxisAccumulator::SourceAxisType QAxisAccumulator::sourceAxisType() const
178{
179 Q_D(const QAxisAccumulator);
180 return d->m_sourceAxisType;
181}
182
183/*!
184 \qmlproperty real Qt3D.Input::AxisAccumulator::value
185
186 The amount to scale the axis value by when accumulating. This can be
187 thought of as the maximum velocity or acceleration the axis can
188 control.
189 */
190
191/*!
192 \property Qt3DInput::QAxisAccumulator::value
193 Returns the accumulated (integrated) value.
194 */
195float QAxisAccumulator::value() const
196{
197 Q_D(const QAxisAccumulator);
198 return d->m_value;
199}
200
201/*!
202 \qmlproperty real Qt3D.Input::Axis::velocity
203 \readonly
204
205 Returns the velocity. If the sourceAxisType is set to Velocity this is
206 simply the value of the source axis multiplied by the scale. If the
207 sourceAxisType is set to Acceleration, the velocity is integrated using the
208 source axis' value as an acceleration.
209*/
210
211/*!
212 Returns the velocity. If the sourceAxisType is set to Velocity this is
213 simply the value of the source axis multiplied by the scale. If the
214 sourceAxisType is set to Acceleration, the velocity is integrated using
215 the source axis' value as an acceleration.
216 */
217float QAxisAccumulator::velocity() const
218{
219 Q_D(const QAxisAccumulator);
220 return d->m_velocity;
221}
222
223/*!
224 \qmlproperty real Qt3D.Input::Axis::scale
225
226 The amount to scale the axis value by when accumulating. This can be
227 thought of as the maximum velocity or acceleration the axis can
228 control.
229*/
230
231/*!
232 The amount to scale the axis value by when accumulating. This can be
233 thought of as the maximum velocity or acceleration the axis can
234 control.
235
236 \return the amount the input axis values are scaled by.
237 */
238float QAxisAccumulator::scale() const
239{
240 Q_D(const QAxisAccumulator);
241 return d->m_scale;
242}
243
244/*!
245 Sets the source axis from which the accumulator should receive values from to
246 \a sourceAxis. How these values are treated is controlled by the sourceAxisType
247 and scale properties.
248 */
249void QAxisAccumulator::setSourceAxis(QAxis *sourceAxis)
250{
251 Q_D(QAxisAccumulator);
252 if (d->m_sourceAxis == sourceAxis)
253 return;
254
255 if (d->m_sourceAxis)
256 d->unregisterDestructionHelper(node: d->m_sourceAxis);
257
258 if (sourceAxis && !sourceAxis->parent())
259 sourceAxis->setParent(this);
260 d->m_sourceAxis = sourceAxis;
261
262 // Ensures proper bookkeeping
263 if (d->m_sourceAxis)
264 d->registerDestructionHelper(node: d->m_sourceAxis, func: &QAxisAccumulator::setSourceAxis, d->m_sourceAxis);
265
266 emit sourceAxisChanged(sourceAxis);
267}
268
269/*!
270 Sets how the accumulator treats the values originating from the \a sourceAxisType.
271 */
272void QAxisAccumulator::setSourceAxisType(QAxisAccumulator::SourceAxisType sourceAxisType)
273{
274 Q_D(QAxisAccumulator);
275 if (d->m_sourceAxisType == sourceAxisType)
276 return;
277
278 d->m_sourceAxisType = sourceAxisType;
279 emit sourceAxisTypeChanged(sourceAxisType);
280}
281
282void QAxisAccumulator::setScale(float scale)
283{
284 Q_D(QAxisAccumulator);
285 if (d->m_scale == scale)
286 return;
287
288 d->m_scale = scale;
289 emit scaleChanged(scale);
290}
291
292// TODO Unused remove in Qt6
293void QAxisAccumulator::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &)
294{
295}
296
297/*! \internal */
298Qt3DCore::QNodeCreatedChangeBasePtr QAxisAccumulator::createNodeCreationChange() const
299{
300 auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QAxisAccumulatorData>::create(arguments: this);
301 auto &data = creationChange->data;
302 Q_D(const QAxisAccumulator);
303 data.sourceAxisId = qIdForNode(node: d->m_sourceAxis);
304 data.sourceAxisType = d->m_sourceAxisType;
305 data.scale = d->m_scale;
306 return creationChange;
307}
308
309} // namespace Qt3DInput
310
311QT_END_NAMESPACE
312

source code of qt3d/src/input/frontend/qaxisaccumulator.cpp