Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquick3dparticlescaleaffector.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5
7#include <qmath.h>
8
10
11/*!
12 \qmltype ScaleAffector3D
13 \inherits Affector3D
14 \inqmlmodule QtQuick3D.Particles3D
15 \brief Particle scale affector.
16 \since 6.4
17
18 Scale affector scales the particle size based on its lifetime and parameters.
19*/
20
21QQuick3DParticleScaleAffector::QQuick3DParticleScaleAffector(QQuick3DNode *parent)
22 : QQuick3DParticleAffector(parent)
23{
24
25}
26
27/*!
28 \qmlproperty real ScaleAffector3D::minSize
29
30 This property holds the minimum size the affector can scale the particle.
31 The default is 1.0.
32*/
33float QQuick3DParticleScaleAffector::minSize() const
34{
35 return m_minSize;
36}
37
38/*!
39 \qmlproperty real ScaleAffector3D::maxSize
40
41 This property holds the maximum size the affector can scale the particle.
42 The default is 1.0.
43*/
44float QQuick3DParticleScaleAffector::maxSize() const
45{
46 return m_maxSize;
47}
48
49/*!
50 \qmlproperty int ScaleAffector3D::duration
51
52 This property holds the duration of scaling cycle in milliseconds.
53 The default is 1000.
54*/
55int QQuick3DParticleScaleAffector::duration() const
56{
57 return m_duration;
58}
59
60/*!
61 \qmlproperty enumeration ScaleAffector3D::ScalingType
62
63 Defines the scaling type of the affector.
64
65 \value ScaleAffector3D.Linear
66 The scale is calculated using the easing curve to interpolate between minimum and maximum
67 scale size between duration milliseconds and then continues from the minimum size.
68 \value ScaleAffector3D.SewSaw
69 The scale is calculated using the easing curve to interpolate between minimum and maximum
70 scale size between duration milliseconds on a rising edge then continues from maximum to minimum
71 on a falling edge.
72 \value ScaleAffector3D.SineWave
73 The scale follows the sine wave. Easing curve is not used.
74 \value ScaleAffector3D.AbsSineWave
75 The scale follows the sine wave except negative values are inverted. Easing curve is not used.
76 \value ScaleAffector3D.Step
77 The scale stays at minimum size until half of the duration milliseconds have passed then steps directly
78 to the maximum size. Easing curve is not used.
79 \value ScaleAffector3D.SmoothStep
80 The scale smootly transitions from minimum to maximum size. Easing curve is not used.
81*/
82
83/*!
84 \qmlproperty ScalingType ScaleAffector3D::type
85
86 This property holds the scaling type of the affector. The default value is \c Linear.
87*/
88QQuick3DParticleScaleAffector::ScalingType QQuick3DParticleScaleAffector::type() const
89{
90 return m_type;
91}
92
93/*!
94 \qmlproperty EasingCurve ScaleAffector3D::easingCurve
95
96 This property holds the \l {QtQuick::PropertyAnimation::easing}{easing curve} providing
97 more fine tuned control on how the scaling occurs. The easing curve is used with \c Linear
98 and \c SewSaw scaling types. The default easing curve provides linear value between [0, 1].
99*/
100QEasingCurve QQuick3DParticleScaleAffector::easingCurve() const
101{
102 return m_easing;
103}
104
105void QQuick3DParticleScaleAffector::setMinSize(float size)
106{
107 if (qFuzzyCompare(size, m_minSize))
108 return;
109 m_minSize = size;
110 Q_EMIT minSizeChanged();
111}
112
113void QQuick3DParticleScaleAffector::setMaxSize(float size)
114{
115 if (qFuzzyCompare(size, m_maxSize))
116 return;
117 m_maxSize = size;
118 Q_EMIT maxSizeChanged();
119}
120
121void QQuick3DParticleScaleAffector::setDuration(int duration)
122{
123 duration = qMax(0, duration);
124 if (duration == m_duration)
125 return;
126 m_duration = duration;
127 Q_EMIT durationChanged();
128}
129
130void QQuick3DParticleScaleAffector::setType(ScalingType type)
131{
132 if (m_type == type)
133 return;
134 m_type = type;
135 Q_EMIT typeChanged();
136}
137
138void QQuick3DParticleScaleAffector::setEasingCurve(const QEasingCurve &curve)
139{
140 if (m_easing == curve)
141 return;
142 m_easing = curve;
143 Q_EMIT easingCurveChanged();
144}
145
146void QQuick3DParticleScaleAffector::prepareToAffect()
147{
148
149}
150
151void QQuick3DParticleScaleAffector::affectParticle(const QQuick3DParticleData &, QQuick3DParticleDataCurrent *d, float time)
152{
153 float scale = 1.0f;
154
155 const auto fract = [](const float v) -> float {
156 return v - qFloor(v);
157 };
158 const auto lerp = [](const float a, const float b, const float f) -> float {
159 return a + (b - a) * f;
160 };
161 const auto smoothstep = [](const float a, const float b, const float f) -> float {
162 return a + (b - a) * f * f * (3.0f - 2.0f * f);
163 };
164
165 float pos = fract(time / float(m_duration * 0.001f));
166 switch (m_type) {
167 case Linear:
168 scale = lerp(m_minSize, m_maxSize, m_easing.valueForProgress(pos));
169 scale = qMax(scale, 0.0f);
170 break;
171 case SewSaw:
172 if (pos < 0.5f)
173 scale = lerp(m_minSize, m_maxSize, m_easing.valueForProgress(pos * 2.0f));
174 else
175 scale = lerp(m_maxSize, m_minSize, m_easing.valueForProgress((pos - 0.5) * 2.0f));
176 scale = qMax(scale, 0.0f);
177 break;
178 case SineWave:
179 scale = m_minSize + (m_maxSize - m_minSize) * (1.0f + qSin(2.0f * M_PI * pos)) * 0.5f;
180 break;
181 case AbsSineWave:
182 scale = m_minSize + (m_maxSize - m_minSize) * qAbs(qSin(2.0f * M_PI * pos));
183 break;
184 case Step:
185 if (pos < 0.5f)
186 scale = m_minSize;
187 else
188 scale = m_maxSize;
189 break;
190 case SmoothStep:
191 scale = smoothstep(m_minSize, m_maxSize, pos);
192 break;
193 }
194
195 d->scale *= scale;
196}
197
198QT_END_NAMESPACE
Combined button and popup list for selecting options.
#define M_PI
Definition qmath.h:200