1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qquick3dparticletrailemitter_p.h"
5
6QT_BEGIN_NAMESPACE
7
8/*!
9 \qmltype TrailEmitter3D
10 \inherits ParticleEmitter3D
11 \inqmlmodule QtQuick3D.Particles3D
12 \brief Emitter for logical particles from other particles.
13 \since 6.2
14
15 TrailEmitter3D is a special emitter for emitting particles with starting positions inherited from
16 other logical particles.
17*/
18
19QQuick3DParticleTrailEmitter::QQuick3DParticleTrailEmitter(QQuick3DNode *parent)
20 : QQuick3DParticleEmitter(parent)
21{
22}
23
24/*!
25 \qmlproperty Particle3D TrailEmitter3D::follow
26
27 This property defines the logical particle which this emitter follows.
28 When the TrailEmitter3D emits particles, center position of those particles
29 will become from the \l Particle3D the emitter follows.
30*/
31QQuick3DParticle *QQuick3DParticleTrailEmitter::follow() const
32{
33 return m_follow;
34}
35
36void QQuick3DParticleTrailEmitter::setFollow(QQuick3DParticle *follow)
37{
38 if (m_follow == follow)
39 return;
40
41 m_follow = follow;
42 Q_EMIT followChanged();
43}
44
45/*!
46 \qmlmethod vector3d TrailEmitter3D::burst(int count)
47
48 This method emits \a count amount of particles from this emitter immediately.
49
50 \note TrailEmitter3D doesn't support other bursting methods. Position always comes
51 from the particle defined with the \l follow property.
52*/
53void QQuick3DParticleTrailEmitter::burst(int count)
54{
55 if (!system())
56 return;
57 QQuick3DParticleEmitBurstData burst;
58 burst.time = system()->currentTime();
59 burst.amount = count;
60 m_bursts << burst;
61}
62
63// Returns true if there are any dynamic bursts
64bool QQuick3DParticleTrailEmitter::hasBursts() const
65{
66 bool dynamicBursts = false;
67 for (auto *burst : std::as_const(t: m_emitBursts)) {
68 if (qobject_cast<QQuick3DParticleDynamicBurst *>(object: burst)) {
69 dynamicBursts = true;
70 break;
71 }
72 }
73 return !m_bursts.empty() || dynamicBursts;
74}
75
76// Called to emit set of particles
77void QQuick3DParticleTrailEmitter::emitTrailParticles(const QVector3D &centerPos, int emitAmount, int triggerType)
78{
79 if (!system())
80 return;
81
82 if (!enabled())
83 return;
84
85 const int systemTime = system()->currentTime();
86 for (auto particle : std::as_const(t&: m_system->m_particles)) {
87 if (particle == m_particle) {
88 emitAmount += getEmitAmountFromDynamicBursts(triggerType);
89 emitAmount = std::min(a: emitAmount, b: int(particle->maxAmount()));
90 float addTime = ((systemTime - m_prevEmitTime) / 1000.0f) / emitAmount;
91 for (int i = 0; i < emitAmount; i++) {
92 // Distribute evenly between previous and current time, important especially
93 // when time has jumped a lot (like a starttime).
94 float startTime = (m_prevEmitTime / 1000.0f) + addTime * float(i);
95 emitParticle(particle, startTime, transform: QMatrix4x4(), parentRotation: QQuaternion(), centerPos);
96 }
97 // Emit bursts, if any
98 for (auto burst : std::as_const(t&: m_bursts)) {
99 int burstAmount = std::min(a: burst.amount, b: int(particle->maxAmount()));
100 float burstTime = float(burst.time / 1000.0f);
101 for (int i = 0; i < burstAmount; i++)
102 emitParticle(particle, startTime: burstTime, transform: QMatrix4x4(), parentRotation: QQuaternion(), centerPos);
103 }
104 }
105 }
106
107 m_prevEmitTime = systemTime;
108}
109
110void QQuick3DParticleTrailEmitter::clearBursts()
111{
112 // After bursts have been emitted, clear the list
113 m_bursts.clear();
114}
115
116QT_END_NAMESPACE
117

source code of qtquick3d/src/quick3dparticles/qquick3dparticletrailemitter.cpp