67 m_prevBurstTime = m_prevEmitTime;
92 if (m_velocity && m_system)
122 m_prevBurstTime = m_prevEmitTime;
158 if (m_emitRate == 0 && m_system) {
180 return m_particleScale;
207 return m_particleEndScale;
239 return m_particleScaleVariation;
275 return m_particleEndScaleVariation;
331 return m_lifeSpanVariation;
360 qWarning(
"ParticleEmitter3D: Emitter and Particle must be in the same system.");
367 if (m_particle && m_system && !m_system->
isShared(m_particle))
396 if (m_shape ==
shape)
400 if (m_shape && m_system)
415 return m_particleRotation;
446 return m_particleRotationVariation;
468 return m_particleRotationVelocity;
501 return m_particleRotationVelocityVariation;
541 m_burstEmitData.
clear();
579 burst.duration = duration;
593 m_burstGenerated =
true;
607 for (
auto emitBurst : std::as_const(m_emitBursts)) {
609 if (qobject_cast<QQuick3DParticleDynamicBurst *>(
emitBurst))
617 for (
int i = 0;
i < emitAmount;
i++) {
624 m_burstGenerated =
true;
631 m_burstGenerated =
false;
637 m_burstGenerated =
false;
644 auto rand = m_system->
rand();
652 particleDataIndex = mbp->
randomIndex(particleDataIndex);
655 int particleIdIndex = m_system->m_particleIdIndex++;
656 if (m_system->m_particleIdIndex == INT_MAX)
657 m_system->m_particleIdIndex = 0;
660 d->index = particleIdIndex;
664 float lifeSpanMs = m_lifeSpanVariation / 1000.0f;
665 float lifeSpanVariationMs = lifeSpanMs - 2.0f * rand->get(particleIdIndex,
QPRand::LifeSpanV) * lifeSpanMs;
666 d->lifetime = (m_lifeSpan / 1000.0f) + lifeSpanVariationMs;
669 float sVar = m_particleScaleVariation - 2.0f * rand->get(particleIdIndex,
QPRand::ScaleV) * m_particleScaleVariation;
670 float endScale = (m_particleEndScale < 0.0f) ? m_particleScale : m_particleEndScale;
671 float sEndVar = (m_particleEndScaleVariation < 0.0f)
673 : m_particleEndScaleVariation - 2.0f * rand->get(particleIdIndex,
QPRand::ScaleEV) * m_particleEndScaleVariation;
674 d->startSize = std::max(0.0f,
float(m_particleScale + sVar));
675 d->endSize = std::max(0.0f,
float(endScale + sEndVar));
696 if (!m_particleRotation.
isNull() || !m_particleRotationVariation.
isNull()) {
698 constexpr float step = 127.0f / 360.0f;
699 rot.
x = m_particleRotation.
x() * step;
700 rot.
y = m_particleRotation.
y() * step;
701 rot.
z = m_particleRotation.
z() * step;
702 rot.
x += (m_particleRotationVariation.
x() - 2.0f * rand->get(particleIdIndex,
QPRand::RotXV) * m_particleRotationVariation.
x()) * step;
703 rot.
y += (m_particleRotationVariation.
y() - 2.0f * rand->get(particleIdIndex,
QPRand::RotYV) * m_particleRotationVariation.
y()) * step;
704 rot.
z += (m_particleRotationVariation.
z() - 2.0f * rand->get(particleIdIndex,
QPRand::RotZV) * m_particleRotationVariation.
z()) * step;
705 d->startRotation = rot;
708 if (!m_particleRotationVelocity.
isNull() || !m_particleRotationVelocityVariation.
isNull()) {
709 float rotVelX = m_particleRotationVelocity.
x();
710 float rotVelY = m_particleRotationVelocity.
y();
711 float rotVelZ = m_particleRotationVelocity.
z();
712 rotVelX += (m_particleRotationVelocityVariation.
x() - 2.0f * rand->get(particleIdIndex,
QPRand::RotXVV) * m_particleRotationVelocityVariation.
x());
713 rotVelY += (m_particleRotationVelocityVariation.
y() - 2.0f * rand->get(particleIdIndex,
QPRand::RotYVV) * m_particleRotationVelocityVariation.
y());
714 rotVelZ += (m_particleRotationVelocityVariation.
z() - 2.0f * rand->get(particleIdIndex,
QPRand::RotZVV) * m_particleRotationVelocityVariation.
z());
718 sign = rotVelX < 0.0f ? -1.0f : 1.0f;
719 rotVelX = std::max(-127.0f, std::min<float>(127.0f,
sign * std::sqrt(abs(rotVelX))));
720 sign = rotVelY < 0.0f ? -1.0f : 1.0f;
721 rotVelY = std::max(-127.0f, std::min<float>(127.0f,
sign * std::sqrt(abs(rotVelY))));
722 sign = rotVelZ < 0.0f ? -1.0f : 1.0f;
723 rotVelZ = std::max(-127.0f, std::min<float>(127.0f,
sign * std::sqrt(abs(rotVelZ))));
724 d->startRotationVelocity = {
qint8(rotVelX),
qint8(rotVelY),
qint8(rotVelZ) };
733 const int randVar = int(rand->get(particleIdIndex,
QPRand::ColorAV) * 256);
734 r = pc.
red() * (1.0f - pcv.
x()) + randVar * pcv.
x();
735 g = pc.
green() * (1.0f - pcv.
y()) + randVar * pcv.
y();
736 b = pc.
blue() * (1.0f - pcv.
z()) + randVar * pcv.
z();
737 a = pc.
alpha() * (1.0f - pcv.
w()) + randVar * pcv.
w();
744 d->startColor = {
r,
g,
b,
a};
748 if (sequence->duration() > 0) {
749 float animationTimeMs = float(sequence->duration()) / 1000.0f;
750 float animationTimeVarMs = float(sequence->durationVariation()) / 1000.0f;
751 animationTimeVarMs = animationTimeVarMs - 2.0f * rand->get(particleIdIndex,
QPRand::SpriteAnimationV) * animationTimeVarMs;
754 d->animationTime = std::max(
MIN_DURATION, animationTimeMs + animationTimeVarMs);
757 d->animationTime =
d->lifetime;
766 const int prevTime = m_prevBurstTime;
768 for (
auto *
burst : std::as_const(m_emitBursts)) {
769 auto *burstPtr = qobject_cast<QQuick3DParticleDynamicBurst *>(
burst);
772 if (!burstPtr->m_enabled)
775 const bool trailTriggering = triggerType && (burstPtr->m_triggerMode) == triggerType;
777 const bool timeTriggeringStart = !triggerType &&
currentTime >= burstPtr->m_time && prevTime <= burstPtr->m_time;
778 if (trailTriggering || timeTriggeringStart) {
779 int burstAmount = burstPtr->m_amount;
780 if (burstPtr->m_amountVariation > 0) {
781 auto rand = m_system->
rand();
782 int randAmount = 2 * rand->
get() * burstPtr->m_amountVariation;
783 burstAmount += burstPtr->m_amountVariation - randAmount;
785 if (burstAmount > 0) {
786 if (timeTriggeringStart && burstPtr->m_duration > 0) {
788 BurstEmitData emitData;
790 emitData.endTime =
currentTime + burstPtr->m_duration;
791 emitData.emitAmount = burstAmount;
792 emitData.prevBurstTime = prevTime;
793 m_burstEmitData << emitData;
796 amount += burstAmount;
802 for (
int burstIndex = 0; burstIndex < m_burstEmitData.
size(); ++burstIndex) {
803 auto &burstData = m_burstEmitData[burstIndex];
804 const int amountLeft = burstData.emitAmount - burstData.emitCounter;
807 amount += amountLeft;
808 m_burstEmitData.
removeAt(burstIndex);
811 const int durationTime =
currentTime - burstData.prevBurstTime;
812 const int burstDurationTime = burstData.endTime - burstData.startTime;
813 int burstAmount = burstData.emitAmount * (float(durationTime) / float(burstDurationTime));
814 burstAmount = std::min(amountLeft, burstAmount);
815 if (burstAmount > 0) {
816 amount += burstAmount;
817 burstData.emitCounter += burstAmount;
835 if (m_emitRate <= 0.0f)
838 float timeChange = m_system->
currentTime() - m_prevEmitTime;
839 float emitAmountF = timeChange / (1000.0f / m_emitRate);
840 int emitAmount = floorf(emitAmountF);
843 if (emitAmount > 0) {
844 m_unemittedF += (emitAmountF - emitAmount);
847 if (m_unemittedF >= 1.0f) {
870 int emitAmount = std::min(
burst.amount,
int(m_particle->
maxAmount()));
871 for (
int i = 0;
i < emitAmount;
i++) {
873 float startTime = (
burst.time / 1000.0f) + (
float(1 +
i) / emitAmount) * ((
burst.duration) / 1000.0f);
890 auto *mbp = qobject_cast<QQuick3DParticleModelBlendParticle *>(m_particle);
899 if (systemTime < m_prevEmitTime) {
901 m_prevEmitTime = systemTime;
905 const int maxLifeSpan = m_lifeSpan + m_lifeSpanVariation;
906 m_prevEmitTime = std::max(m_prevEmitTime, systemTime - maxLifeSpan);
910 if (!m_burstGenerated)
923 emitAmount = std::min(emitAmount,
int(m_particle->
maxAmount()));
924 for (
int i = 0;
i < emitAmount;
i++) {
927 float startTime = (m_prevEmitTime / 1000.0f) + (
float(1+
i) / emitAmount) * ((systemTime - m_prevEmitTime) / 1000.0f);
931 m_prevEmitTime = systemTime;
946 const int maxLifeSpan = m_lifeSpan + m_lifeSpanVariation;
947 m_prevEmitTime = std::max(m_prevEmitTime, systemTime - maxLifeSpan);
963 m_prevEmitTime = systemTime;
968 if (!m_system && qobject_cast<QQuick3DParticleSystem *>(parentItem()))
969 setSystem(qobject_cast<QQuick3DParticleSystem *>(parentItem()));
1023 return m_emitBursts.
size();
1028 return m_emitBursts.
at(
index);
1032 m_emitBursts.
clear();
The QColor class provides colors based on RGB, HSV or CMYK values.
int alpha() const noexcept
Returns the alpha color component of this color.
int red() const noexcept
Returns the red color component of this color.
int blue() const noexcept
Returns the blue color component of this color.
int green() const noexcept
Returns the green color component of this color.
qsizetype size() const noexcept
bool isEmpty() const noexcept
void removeAt(qsizetype i)
const_reference at(qsizetype i) const noexcept
qsizetype removeAll(const AT &t)
void removeLast() noexcept
void append(parameter_type t)
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
QVector4D column(int index) const
Returns the elements of column index as a 4D vector.
QMatrix4x4 inverted(bool *invertible=nullptr) const
Returns the inverse of this matrix.
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
float get(int particleIndex, UserType user=Default)
The QQmlListProperty class allows applications to expose list-like properties of QObject-derived clas...
The QQuaternion class represents a quaternion consisting of a vector and scalar.
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
QMatrix4x4 sceneTransform
QQuick3DNode * parentNode() const
QQuick3DParticleSystem * m_system
virtual QVector3D getPosition(int particleIndex)=0
virtual QVector3D sample(const QQuick3DParticleData &d)=0
QQuick3DParticleSystem * m_system
void setShape(QQuick3DParticleAbstractShape *shape)
qsizetype emitBurstCount() const
void setParticleEndScaleVariation(float particleEndScaleVariation)
QQmlListProperty< QQuick3DParticleEmitBurst > emitBursts
\qmlproperty List<EmitBurst3D> ParticleEmitter3D::emitBursts
void setParticleRotationVelocityVariation(const QVector3D &particleRotationVelocityVariation)
void appendEmitBurst(QQuick3DParticleEmitBurst *)
void setEnabled(bool enabled)
void particleEndScaleChanged()
void setParticleRotation(const QVector3D &particleRotation)
void setLifeSpanVariation(int lifeSpanVariation)
void particleRotationVariationChanged()
void setDepthBias(float bias)
float particleEndScaleVariation
void lifeSpanVariationChanged()
void setParticleEndScale(float particleEndScale)
void setParticleScaleVariation(float particleScaleVariation)
void particleRotationVelocityChanged()
void particleScaleVariationChanged()
void setParticleRotationVariation(const QVector3D &particleRotationVariation)
int getEmitAmountFromDynamicBursts(int triggerType=0)
QQuick3DParticleSystem * system
void emitActivationNodeParticles(QQuick3DParticleModelBlendParticle *particle)
QQuick3DParticle * particle
void particleEndScaleVariationChanged()
void setVelocity(QQuick3DParticleDirection *velocity)
QVector3D particleRotation
void setParticle(QQuick3DParticle *particle)
void emitParticlesBurst(const QQuick3DParticleEmitBurstData &burst)
void particleScaleChanged()
QVector3D particleRotationVelocity
QQuick3DParticleEmitBurst * emitBurst(qsizetype) const
float particleScaleVariation
QQuick3DParticleAbstractShape * shape
QVector3D particleRotationVariation
QQuick3DParticleDirection * velocity
void replaceEmitBurst(qsizetype, QQuick3DParticleEmitBurst *)
QVector3D particleRotationVelocityVariation
virtual Q_INVOKABLE void burst(int count)
\qmlmethod vector3d ParticleEmitter3D::burst(int count)
void setLifeSpan(int lifeSpan)
void generateEmitBursts()
void setParticleRotationVelocity(const QVector3D &particleRotationVelocity)
void removeLastEmitBurst()
~QQuick3DParticleEmitter() override
void emitParticle(QQuick3DParticle *particle, float startTime, const QMatrix4x4 &transform, const QQuaternion &parentRotation, const QVector3D ¢erPos, int index=-1)
void registerEmitBurst(QQuick3DParticleEmitBurst *emitBurst)
void setEmitRate(float emitRate)
void unRegisterEmitBurst(QQuick3DParticleEmitBurst *emitBurst)
QQuick3DParticleEmitter(QQuick3DNode *parent=nullptr)
\qmltype ParticleEmitter3D \inherits Node \inqmlmodule QtQuick3D.Particles3D
void setParticleScale(float particleScale)
void particleRotationChanged()
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
void setSystem(QQuick3DParticleSystem *system)
void particleRotationVariationVelocityChanged()
QVector3D particleCenter(int particleIndex) const
ModelBlendEmitMode emitMode
bool lastParticle() const
ModelBlendMode modelBlendMode
int randomIndex(int particleIndex)
void unRegisterParticleEmitter(QQuick3DParticleEmitter *e)
bool isShared(const QQuick3DParticle *particle) const
void registerParticleEmitter(QQuick3DParticleEmitter *e)
int currentTime() const
Returns the current time of the system (m_time + m_startTime).
QList< QQuick3DParticleData > m_particleData
QQuick3DParticleSpriteSequence * m_spriteSequence
virtual int nextCurrentIndex(const QQuick3DParticleEmitter *emitter)
void setSystem(QQuick3DParticleSystem *system)
QQuick3DParticleSystem * system() const
virtual void setDepthBias(float bias)
bool unifiedColorVariation
void updateBurstIndex(int amount)
The QVector3D class represents a vector or vertex in 3D space.
constexpr bool isNull() const noexcept
Returns true if the x, y, and z coordinates are set to 0.0, otherwise returns false.
constexpr float y() const noexcept
Returns the y coordinate of this point.
constexpr float x() const noexcept
Returns the x coordinate of this point.
static constexpr float dotProduct(QVector3D v1, QVector3D v2) noexcept
Returns the dot product of v1 and v2.
constexpr float z() const noexcept
Returns the z coordinate of this point.
The QVector4D class represents a vector or vertex in 4D space.
constexpr float x() const noexcept
Returns the x coordinate of this point.
constexpr float w() const noexcept
Returns the w coordinate of this point.
constexpr float y() const noexcept
Returns the y coordinate of this point.
constexpr QVector3D toVector3D() const noexcept
Returns the 3D vector form of this 4D vector, dropping the w coordinate.
constexpr float z() const noexcept
Returns the z coordinate of this point.
qDeleteAll(list.begin(), list.end())
Combined button and popup list for selecting options.
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLenum GLsizei count
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLuint GLenum GLenum transform
QT_BEGIN_NAMESPACE const float MIN_DURATION
\qmltype Attractor3D \inherits Affector3D \inqmlmodule QtQuick3D.Particles3D
QQuick3DNode * getSharedParentNode(QQuick3DNode *node, QQuick3DNode *system)
QMatrix4x4 calculateParticleTransform(const QQuick3DNode *parent, const QQuick3DNode *systemSharedParent)
QQuaternion calculateParticleRotation(const QQuick3DNode *parent, const QQuick3DNode *systemSharedParent)
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
QT_BEGIN_NAMESPACE typedef signed char qint8
static double currentTime()
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent