8#include <private/qqmlglobal_p.h>
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
38
39
40
41
42
44
45
46
47
48
50
51
52
53
54
55
56
57
58
59
60
61
62
64
65
66
67
68
69
70
72
73
74
75
76
77
78
79
81
82
83
84
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100QQuickParticleAffector::QQuickParticleAffector(QQuickItem *parent) :
101 QQuickItem(parent), m_needsReset(
false), m_ignoresTime(
false), m_onceOff(
false), m_enabled(
true)
102 , m_system(
nullptr), m_updateIntSet(
false), m_shape(
new QQuickParticleExtruder(
this))
106bool QQuickParticleAffector::isAffectedConnected()
108 IS_SIGNAL_CONNECTED(
this, QQuickParticleAffector, affected, (qreal,qreal));
112void QQuickParticleAffector::componentComplete()
114 if (!m_system && qobject_cast<QQuickParticleSystem*>(parentItem()))
115 setSystem(qobject_cast<QQuickParticleSystem*>(parentItem()));
116 QQuickItem::componentComplete();
119bool QQuickParticleAffector::activeGroup(
int g) {
125 foreach (
const QString &p, m_groups)
126 m_groupIds << m_system->groupIds[p];
127 m_updateIntSet =
false;
129 return m_groupIds.isEmpty() || m_groupIds.contains(g);
132bool QQuickParticleAffector::shouldAffect(QQuickParticleData* d)
139 if (activeGroup(d->groupId)){
140 if ((m_onceOff && m_onceOffed.contains(std::make_pair(d->groupId, d->index)))
141 || !d->stillAlive(m_system))
144 if (width() == 0 || height() == 0
145 || m_shape->contains(QRectF(m_offset.x(), m_offset.y(), width(), height()), QPointF(d->curX(m_system), d->curY(m_system)))){
146 if (m_whenCollidingWith.isEmpty() || isColliding(d)){
155void QQuickParticleAffector::postAffect(QQuickParticleData* d)
160 m_system->needsReset << d;
162 m_onceOffed << std::make_pair(d->groupId, d->index);
163 if (isAffectedConnected())
164 emit affected(d->curX(m_system), d->curY(m_system));
167const qreal QQuickParticleAffector::simulationDelta = 0.020;
168const qreal QQuickParticleAffector::simulationCutoff = 1.000;
170void QQuickParticleAffector::affectSystem(qreal dt)
182 for (QQuickParticleGroupData* gd : std::as_const(m_system->groupData)) {
183 if (activeGroup(gd->index)) {
184 for (QQuickParticleData* d : std::as_const(gd->data)) {
185 if (shouldAffect(d)) {
186 bool affected =
false;
188 if (!m_ignoresTime && myDt < simulationCutoff) {
189 int realTime = m_system->timeInt;
190 m_system->timeInt -= myDt * 1000.0;
191 while (myDt > simulationDelta) {
192 m_system->timeInt += simulationDelta * 1000.0;
193 if (d->alive(m_system))
194 affected = affectParticle(d, simulationDelta) || affected;
195 myDt -= simulationDelta;
197 m_system->timeInt = realTime;
200 affected = affectParticle(d, myDt) || affected;
209bool QQuickParticleAffector::affectParticle(QQuickParticleData *, qreal )
214void QQuickParticleAffector::reset(QQuickParticleData* pd)
217 if (activeGroup(pd->groupId))
218 m_onceOffed.remove(std::make_pair(pd->groupId, pd->index));
221void QQuickParticleAffector::updateOffsets()
224 m_offset = m_system->mapFromItem(
this, QPointF(0, 0));
227bool QQuickParticleAffector::isColliding(QQuickParticleData *d)
const
232 qreal myCurX = d->curX(m_system);
233 qreal myCurY = d->curY(m_system);
234 qreal myCurSize = d->curSize(m_system) / 2;
235 foreach (
const QString &group, m_whenCollidingWith){
236 foreach (QQuickParticleData* other, m_system->groupData[m_system->groupIds[group]]->data){
237 if (!other->stillAlive(m_system))
239 qreal otherCurX = other->curX(m_system);
240 qreal otherCurY = other->curY(m_system);
241 qreal otherCurSize = other->curSize(m_system) / 2;
242 if ((myCurX + myCurSize > otherCurX - otherCurSize
243 && myCurX - myCurSize < otherCurX + otherCurSize)
244 && (myCurY + myCurSize > otherCurY - otherCurSize
245 && myCurY - myCurSize < otherCurY + otherCurSize))
254#include "moc_qquickparticleaffector_p.cpp"