29QQuickTrailEmitter::QQuickTrailEmitter(QQuickItem *parent) :
30 QQuickParticleEmitter(parent)
31 , m_particlesPerParticlePerSecond(0)
33 , m_emitterXVariation(0)
34 , m_emitterYVariation(0)
36 , m_emissionExtruder(
nullptr)
37 , m_defaultEmissionExtruder(
new QQuickParticleExtruder(
this))
40 connect(
this, &QQuickTrailEmitter::followChanged,
41 this, &QQuickTrailEmitter::recalcParticlesPerSecond);
42 connect(
this, &QQuickTrailEmitter::particleDurationChanged,
43 this, &QQuickTrailEmitter::recalcParticlesPerSecond);
44 connect(
this, &QQuickTrailEmitter::particlesPerParticlePerSecondChanged,
45 this, &QQuickTrailEmitter::recalcParticlesPerSecond);
124void QQuickTrailEmitter::emitWindow(
int timeStamp)
126 if (m_system ==
nullptr)
128 if (!m_enabled && !m_pulseLeft && m_burstQueue.isEmpty())
130 if (m_followCount != m_system->groupData[m_system->groupIds[m_follow]]->size()){
131 qreal oldPPS = m_particlesPerSecond;
132 recalcParticlesPerSecond();
133 if (m_particlesPerSecond != oldPPS)
138 m_pulseLeft -= timeStamp - m_lastTimeStamp * 1000.;
139 if (m_pulseLeft < 0){
140 timeStamp += m_pulseLeft;
146 qreal time = timeStamp / 1000.;
147 qreal particleRatio = 1. / m_particlesPerParticlePerSecond;
149 qreal maxLife = (m_particleDuration + m_particleDurationVariation)/1000.0;
152 QPointF offset = m_system->mapFromItem(
this, QPointF(0, 0));
153 qreal sizeAtEnd = m_particleEndSize >= 0 ? m_particleEndSize : m_particleSize;
155 int gId = m_system->groupIds[m_follow];
156 int gId2 = groupId();
157 for (
int i=0; i<m_system->groupData[gId]->data.size(); i++) {
158 QQuickParticleData *d = m_system->groupData[gId]->data[i];
159 if (!d->stillAlive(m_system)){
160 m_lastEmission[i] = time;
163 pt = m_lastEmission[i];
166 if (pt + maxLife < time)
169 if ((width() || height()) && !effectiveExtruder()->contains(QRectF(offset.x(), offset.y(), width(), height()),
170 QPointF(d->curX(m_system), d->curY(m_system)))) {
171 m_lastEmission[d->index] = time;
175 QList<QQuickParticleData*> toEmit;
177 while (pt < time || !m_burstQueue.isEmpty()){
178 QQuickParticleData* datum = m_system->newDatum(gId2, !m_overwrite);
184 + (QRandomGenerator::global()->bounded((m_particleDurationVariation*2) + 1) - m_particleDurationVariation))
189 qreal followT = pt - d->t;
190 qreal followT2 = followT * followT * 0.5;
191 qreal eW = m_emitterXVariation < 0 ? d->curSize(m_system) : m_emitterXVariation;
192 qreal eH = m_emitterYVariation < 0 ? d->curSize(m_system) : m_emitterYVariation;
194 QRectF boundsRect(d->x - offset.x() + d->vx * followT + d->ax * followT2 - eW/2,
195 d->y - offset.y() + d->vy * followT + d->ay * followT2 - eH/2,
198 QQuickParticleExtruder* effectiveEmissionExtruder = m_emissionExtruder ? m_emissionExtruder : m_defaultEmissionExtruder;
199 const QPointF &newPos = effectiveEmissionExtruder->extrude(boundsRect);
200 datum->x = newPos.x();
201 datum->y = newPos.y();
204 const QPointF &velocity = m_velocity->sample(newPos);
205 datum->vx = velocity.x()
206 + m_velocity_from_movement * d->vx;
207 datum->vy = velocity.y()
208 + m_velocity_from_movement * d->vy;
211 const QPointF &accel = m_acceleration->sample(newPos);
212 datum->ax = accel.x();
213 datum->ay = accel.y();
216 float sizeVariation = -m_particleSizeVariation
217 + QRandomGenerator::global()->generateDouble() * m_particleSizeVariation * 2;
219 float size = qMax((qreal)0.0, m_particleSize + sizeVariation);
220 float endSize = qMax((qreal)0.0, sizeAtEnd + sizeVariation);
222 datum->size = size *
float(m_enabled);
223 datum->endSize = endSize *
float(m_enabled);
227 m_system->emitParticle(datum,
this);
229 if (!m_burstQueue.isEmpty()){
230 m_burstQueue.first().first--;
231 if (m_burstQueue.first().first <= 0)
232 m_burstQueue.pop_front();
238 foreach (QQuickParticleData* d, toEmit)
239 m_system->emitParticle(d,
this);
241 if (isEmitConnected() || isEmitFollowConnected()) {
243 QList<QQuickV4ParticleData> particles;
244 particles.reserve(toEmit.size());
245 for (QQuickParticleData *particle : std::as_const(toEmit))
246 particles.push_back(particle->v4Value(m_system));
248 if (isEmitFollowConnected()) {
250 emit emitFollowParticles(particles, d->v4Value(m_system));
251 }
else if (isEmitConnected()) {
252 emit emitParticles(particles);
255 m_lastEmission[d->index] = pt;
258 m_lastTimeStamp = time;