28QQuickTrailEmitter::QQuickTrailEmitter(QQuickItem *parent) :
29 QQuickParticleEmitter(parent)
30 , m_particlesPerParticlePerSecond(0)
32 , m_emitterXVariation(0)
33 , m_emitterYVariation(0)
35 , m_emissionExtruder(
nullptr)
36 , m_defaultEmissionExtruder(
new QQuickParticleExtruder(
this))
39 connect(
this, &QQuickTrailEmitter::followChanged,
40 this, &QQuickTrailEmitter::recalcParticlesPerSecond);
41 connect(
this, &QQuickTrailEmitter::particleDurationChanged,
42 this, &QQuickTrailEmitter::recalcParticlesPerSecond);
43 connect(
this, &QQuickTrailEmitter::particlesPerParticlePerSecondChanged,
44 this, &QQuickTrailEmitter::recalcParticlesPerSecond);
123void QQuickTrailEmitter::emitWindow(
int timeStamp)
125 if (m_system ==
nullptr)
127 if (!m_enabled && !m_pulseLeft && m_burstQueue.isEmpty())
129 if (m_followCount != m_system->groupData[m_system->groupIds[m_follow]]->size()){
130 qreal oldPPS = m_particlesPerSecond;
131 recalcParticlesPerSecond();
132 if (m_particlesPerSecond != oldPPS)
137 m_pulseLeft -= timeStamp - m_lastTimeStamp * 1000.;
138 if (m_pulseLeft < 0){
139 timeStamp += m_pulseLeft;
145 qreal time = timeStamp / 1000.;
146 qreal particleRatio = 1. / m_particlesPerParticlePerSecond;
148 qreal maxLife = (m_particleDuration + m_particleDurationVariation)/1000.0;
151 QPointF offset = m_system->mapFromItem(
this, QPointF(0, 0));
152 qreal sizeAtEnd = m_particleEndSize >= 0 ? m_particleEndSize : m_particleSize;
154 int gId = m_system->groupIds[m_follow];
155 int gId2 = groupId();
156 for (
int i=0; i<m_system->groupData[gId]->data.size(); i++) {
157 QQuickParticleData *d = m_system->groupData[gId]->data[i];
158 if (!d->stillAlive(m_system)){
159 m_lastEmission[i] = time;
162 pt = m_lastEmission[i];
165 if (pt + maxLife < time)
168 if ((width() || height()) && !effectiveExtruder()->contains(QRectF(offset.x(), offset.y(), width(), height()),
169 QPointF(d->curX(m_system), d->curY(m_system)))) {
170 m_lastEmission[d->index] = time;
174 QList<QQuickParticleData*> toEmit;
176 while (pt < time || !m_burstQueue.isEmpty()){
177 QQuickParticleData* datum = m_system->newDatum(gId2, !m_overwrite);
183 + (QRandomGenerator::global()->bounded((m_particleDurationVariation*2) + 1) - m_particleDurationVariation))
188 qreal followT = pt - d->t;
189 qreal followT2 = followT * followT * 0.5;
190 qreal eW = m_emitterXVariation < 0 ? d->curSize(m_system) : m_emitterXVariation;
191 qreal eH = m_emitterYVariation < 0 ? d->curSize(m_system) : m_emitterYVariation;
193 QRectF boundsRect(d->x - offset.x() + d->vx * followT + d->ax * followT2 - eW/2,
194 d->y - offset.y() + d->vy * followT + d->ay * followT2 - eH/2,
197 QQuickParticleExtruder* effectiveEmissionExtruder = m_emissionExtruder ? m_emissionExtruder : m_defaultEmissionExtruder;
198 const QPointF &newPos = effectiveEmissionExtruder->extrude(boundsRect);
199 datum->x = newPos.x();
200 datum->y = newPos.y();
203 const QPointF &velocity = m_velocity->sample(newPos);
204 datum->vx = velocity.x()
205 + m_velocity_from_movement * d->vx;
206 datum->vy = velocity.y()
207 + m_velocity_from_movement * d->vy;
210 const QPointF &accel = m_acceleration->sample(newPos);
211 datum->ax = accel.x();
212 datum->ay = accel.y();
215 float sizeVariation = -m_particleSizeVariation
216 + QRandomGenerator::global()->generateDouble() * m_particleSizeVariation * 2;
218 float size = qMax((qreal)0.0, m_particleSize + sizeVariation);
219 float endSize = qMax((qreal)0.0, sizeAtEnd + sizeVariation);
221 datum->size = size *
float(m_enabled);
222 datum->endSize = endSize *
float(m_enabled);
226 m_system->emitParticle(datum,
this);
228 if (!m_burstQueue.isEmpty()){
229 m_burstQueue.first().first--;
230 if (m_burstQueue.first().first <= 0)
231 m_burstQueue.pop_front();
237 foreach (QQuickParticleData* d, toEmit)
238 m_system->emitParticle(d,
this);
240 if (isEmitConnected() || isEmitFollowConnected()) {
242 QList<QQuickV4ParticleData> particles;
243 particles.reserve(toEmit.size());
244 for (QQuickParticleData *particle : std::as_const(toEmit))
245 particles.push_back(particle->v4Value(m_system));
247 if (isEmitFollowConnected()) {
249 emit emitFollowParticles(particles, d->v4Value(m_system));
250 }
else if (isEmitConnected()) {
251 emit emitParticles(particles);
254 m_lastEmission[d->index] = pt;
257 m_lastTimeStamp = time;