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 "qaxisaccumulator.h" |
5 | #include "qaxisaccumulator_p.h" |
6 | |
7 | #include <Qt3DInput/qaxis.h> |
8 | |
9 | QT_BEGIN_NAMESPACE |
10 | |
11 | namespace Qt3DInput { |
12 | |
13 | /*! |
14 | Constructs a new QAxisAccumulator instance with \a parent. |
15 | \class Qt3DInput::QAxisAccumulator |
16 | \inmodule Qt3DInput |
17 | \inherits Qt3DCore::QComponent |
18 | \brief QAxisAccumulator processes velocity or acceleration data from a QAxis. |
19 | \since 5.8 |
20 | |
21 | A Qt3DInput::QAxis reports the current position of an axis on an input |
22 | device. When the axis is returned to its neutral position the value of that |
23 | axis returns to 0. Often, it is required to have the input from an axis |
24 | control a variable in other ways, for example treating the value from the |
25 | Qt3DInput::QAxis as a velocity (first derivative with respect to time) or |
26 | as an acceleration (second derivative with respect to time). This can be |
27 | done with user code or with a Qt3DLogic::QFrameAction but those approached |
28 | are not ideal as they add more work to the main thread and are inherently |
29 | imperative. The Qt3DInput::QAxisAccumulator class allows for this common |
30 | task to be performed on the Qt 3D backend and be specified in a declarative |
31 | manner. |
32 | */ |
33 | |
34 | /*! |
35 | \qmltype AxisAccumulator |
36 | \inqmlmodule Qt3D.Input |
37 | \instantiates Qt3DInput::QAxisAccumulator |
38 | \brief QML frontend for the Qt3DInput::QAxisAccumulator C++ class. |
39 | \since 5.8 |
40 | |
41 | An Axis reports the current position of an axis on an input device. When the |
42 | axis is returned to its neutral position the value of that axis returns to 0. |
43 | Often, it is required to have the input from an axis control a variable in |
44 | other ways, for example treating the value from the Axis as a velocity (first |
45 | derivative with respect to time) or as an acceleration (second derivative with |
46 | respect to time). This can be done with user code or with a FrameAction but |
47 | those approached are not ideal as they add more work to the main thread and |
48 | are inherently imperative. The AxisAccumulator class allows for this common |
49 | task to be performed on the Qt 3D backend and be specified in a declarative |
50 | manner. |
51 | */ |
52 | |
53 | /*! |
54 | \qmlproperty int Qt3D.Input::Axis::value |
55 | \readonly |
56 | |
57 | Holds the value accumulated from the sourceAxis. |
58 | */ |
59 | |
60 | /*! |
61 | * \enum Qt3DInput::QAxisAccumulator::SourceAxisType |
62 | * |
63 | * \value Velocity |
64 | * \value Acceleration |
65 | */ |
66 | |
67 | /*! \internal */ |
68 | QAxisAccumulatorPrivate::QAxisAccumulatorPrivate() |
69 | : Qt3DCore::QComponentPrivate() |
70 | , m_sourceAxis(nullptr) |
71 | , m_sourceAxisType(QAxisAccumulator::Velocity) |
72 | , m_scale(1.0f) |
73 | , m_value(0.0f) |
74 | , m_velocity(0.0f) |
75 | { |
76 | } |
77 | |
78 | /*! \internal */ |
79 | void QAxisAccumulatorPrivate::setValue(float value) |
80 | { |
81 | if (value != m_value) { |
82 | Q_Q(QAxisAccumulator); |
83 | m_value = value; |
84 | const bool wasBlocked = q->blockNotifications(block: true); |
85 | emit q->valueChanged(value: m_value); |
86 | q->blockNotifications(block: wasBlocked); |
87 | } |
88 | } |
89 | |
90 | /*! \internal */ |
91 | void QAxisAccumulatorPrivate::setVelocity(float velocity) |
92 | { |
93 | if (velocity != m_velocity) { |
94 | Q_Q(QAxisAccumulator); |
95 | m_velocity = velocity; |
96 | const bool wasBlocked = q->blockNotifications(block: true); |
97 | emit q->velocityChanged(value: m_velocity); |
98 | q->blockNotifications(block: wasBlocked); |
99 | } |
100 | } |
101 | |
102 | /*! |
103 | Constructs a new QAxisAccumulator instance with parent \a parent. |
104 | */ |
105 | QAxisAccumulator::QAxisAccumulator(Qt3DCore::QNode *parent) |
106 | : Qt3DCore::QComponent(*new QAxisAccumulatorPrivate, parent) |
107 | { |
108 | } |
109 | |
110 | /*! \internal */ |
111 | QAxisAccumulator::~QAxisAccumulator() |
112 | { |
113 | } |
114 | |
115 | /*! |
116 | \qmlproperty Axis Qt3D.Input::AxisAccumulator::sourceAxis |
117 | |
118 | The Axis for which the accumulator should integrate axis values. |
119 | */ |
120 | |
121 | /*! |
122 | \return QAxis for which the accumulator should integrate axis values. |
123 | */ |
124 | QAxis *QAxisAccumulator::sourceAxis() const |
125 | { |
126 | Q_D(const QAxisAccumulator); |
127 | return d->m_sourceAxis; |
128 | } |
129 | |
130 | /*! |
131 | \qmlproperty SourceAxisType Qt3D.Input::AxisAccumulator::sourceAxisType |
132 | |
133 | The sourceAxisType property specifies how the accumulator treats the values |
134 | from the source axis. |
135 | */ |
136 | |
137 | /*! |
138 | \return how the accumulator treats the value of the sourceAxis. |
139 | */ |
140 | QAxisAccumulator::SourceAxisType QAxisAccumulator::sourceAxisType() const |
141 | { |
142 | Q_D(const QAxisAccumulator); |
143 | return d->m_sourceAxisType; |
144 | } |
145 | |
146 | /*! |
147 | \qmlproperty real Qt3D.Input::AxisAccumulator::value |
148 | |
149 | The amount to scale the axis value by when accumulating. This can be |
150 | thought of as the maximum velocity or acceleration the axis can |
151 | control. |
152 | */ |
153 | |
154 | /*! |
155 | \property Qt3DInput::QAxisAccumulator::value |
156 | Returns the accumulated (integrated) value. |
157 | */ |
158 | float QAxisAccumulator::value() const |
159 | { |
160 | Q_D(const QAxisAccumulator); |
161 | return d->m_value; |
162 | } |
163 | |
164 | /*! |
165 | \qmlproperty real Qt3D.Input::Axis::velocity |
166 | \readonly |
167 | |
168 | Returns the velocity. If the sourceAxisType is set to Velocity this is |
169 | simply the value of the source axis multiplied by the scale. If the |
170 | sourceAxisType is set to Acceleration, the velocity is integrated using the |
171 | source axis' value as an acceleration. |
172 | */ |
173 | |
174 | /*! |
175 | Returns the velocity. If the sourceAxisType is set to Velocity this is |
176 | simply the value of the source axis multiplied by the scale. If the |
177 | sourceAxisType is set to Acceleration, the velocity is integrated using |
178 | the source axis' value as an acceleration. |
179 | */ |
180 | float QAxisAccumulator::velocity() const |
181 | { |
182 | Q_D(const QAxisAccumulator); |
183 | return d->m_velocity; |
184 | } |
185 | |
186 | /*! |
187 | \qmlproperty real Qt3D.Input::Axis::scale |
188 | |
189 | The amount to scale the axis value by when accumulating. This can be |
190 | thought of as the maximum velocity or acceleration the axis can |
191 | control. |
192 | */ |
193 | |
194 | /*! |
195 | The amount to scale the axis value by when accumulating. This can be |
196 | thought of as the maximum velocity or acceleration the axis can |
197 | control. |
198 | |
199 | \return the amount the input axis values are scaled by. |
200 | */ |
201 | float QAxisAccumulator::scale() const |
202 | { |
203 | Q_D(const QAxisAccumulator); |
204 | return d->m_scale; |
205 | } |
206 | |
207 | /*! |
208 | Sets the source axis from which the accumulator should receive values from to |
209 | \a sourceAxis. How these values are treated is controlled by the sourceAxisType |
210 | and scale properties. |
211 | */ |
212 | void QAxisAccumulator::setSourceAxis(QAxis *sourceAxis) |
213 | { |
214 | Q_D(QAxisAccumulator); |
215 | if (d->m_sourceAxis == sourceAxis) |
216 | return; |
217 | |
218 | if (d->m_sourceAxis) |
219 | d->unregisterDestructionHelper(node: d->m_sourceAxis); |
220 | |
221 | if (sourceAxis && !sourceAxis->parent()) |
222 | sourceAxis->setParent(this); |
223 | d->m_sourceAxis = sourceAxis; |
224 | |
225 | // Ensures proper bookkeeping |
226 | if (d->m_sourceAxis) |
227 | d->registerDestructionHelper(node: d->m_sourceAxis, func: &QAxisAccumulator::setSourceAxis, d->m_sourceAxis); |
228 | |
229 | emit sourceAxisChanged(sourceAxis); |
230 | } |
231 | |
232 | /*! |
233 | Sets how the accumulator treats the values originating from the \a sourceAxisType. |
234 | */ |
235 | void QAxisAccumulator::setSourceAxisType(QAxisAccumulator::SourceAxisType sourceAxisType) |
236 | { |
237 | Q_D(QAxisAccumulator); |
238 | if (d->m_sourceAxisType == sourceAxisType) |
239 | return; |
240 | |
241 | d->m_sourceAxisType = sourceAxisType; |
242 | emit sourceAxisTypeChanged(sourceAxisType); |
243 | } |
244 | |
245 | void QAxisAccumulator::setScale(float scale) |
246 | { |
247 | Q_D(QAxisAccumulator); |
248 | if (d->m_scale == scale) |
249 | return; |
250 | |
251 | d->m_scale = scale; |
252 | emit scaleChanged(scale); |
253 | } |
254 | |
255 | } // namespace Qt3DInput |
256 | |
257 | QT_END_NAMESPACE |
258 | |
259 | #include "moc_qaxisaccumulator.cpp" |
260 | |