Revision control
Copy as Markdown
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
// Qt-Security score:significant reason:default
#ifndef QQUICK3DSPRITEPARTICLE_H
#define QQUICK3DSPRITEPARTICLE_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QColor>
#include <QVector4D>
#include <QtQml/QQmlListProperty>
#include <QtQuick3DParticles/private/qquick3dparticle_p.h>
#include <QtQuick3DParticles/private/qquick3dparticlesystem_p.h>
#include <QtQuick3DParticles/private/qquick3dparticledata_p.h>
#include <QtQuick3DParticles/private/qquick3dparticlespritesequence_p.h>
#include <QtQuick3D/private/qquick3dabstractlight_p.h>
#include <QtQuick3DRuntimeRender/private/qssgrenderparticles_p.h>
#include <array>
QT_BEGIN_NAMESPACE
class Q_QUICK3DPARTICLES_EXPORT QQuick3DParticleSpriteParticle : public QQuick3DParticle
{
Q_OBJECT
Q_PROPERTY(BlendMode blendMode READ blendMode WRITE setBlendMode NOTIFY blendModeChanged)
Q_PROPERTY(QQuick3DTexture *sprite READ sprite WRITE setSprite NOTIFY spriteChanged)
Q_PROPERTY(QQuick3DParticleSpriteSequence *spriteSequence READ spriteSequence WRITE setSpriteSequence NOTIFY spriteSequenceChanged)
Q_PROPERTY(bool billboard READ billboard WRITE setBillboard NOTIFY billboardChanged)
Q_PROPERTY(float particleScale READ particleScale WRITE setParticleScale NOTIFY particleScaleChanged)
Q_PROPERTY(QQuick3DTexture *colorTable READ colorTable WRITE setColorTable NOTIFY colorTableChanged)
Q_PROPERTY(QQmlListProperty<QQuick3DAbstractLight> lights READ lights NOTIFY lightsChanged REVISION(6, 3))
Q_PROPERTY(float offsetX READ offsetX WRITE setOffsetX NOTIFY offsetXChanged REVISION(6, 3))
Q_PROPERTY(float offsetY READ offsetY WRITE setOffsetY NOTIFY offsetYChanged REVISION(6, 3))
Q_PROPERTY(bool castsReflections READ castsReflections WRITE setCastsReflections NOTIFY castsReflectionsChanged REVISION(6, 4))
QML_NAMED_ELEMENT(SpriteParticle3D)
QML_ADDED_IN_VERSION(6, 2)
public:
enum BlendMode { SourceOver = 0, Screen, Multiply };
Q_ENUM(BlendMode)
QQuick3DParticleSpriteParticle(QQuick3DNode *parent = nullptr);
~QQuick3DParticleSpriteParticle() override;
BlendMode blendMode() const;
QQuick3DTexture *sprite() const;
QQuick3DParticleSpriteSequence *spriteSequence() const;
bool billboard() const;
float particleScale() const;
QQuick3DTexture *colorTable() const;
Q_REVISION(6, 3) QQmlListProperty<QQuick3DAbstractLight> lights();
float offsetX() const;
float offsetY() const;
Q_REVISION(6, 4) bool castsReflections() const;
public Q_SLOTS:
void setBlendMode(QQuick3DParticleSpriteParticle::BlendMode blendMode);
void setSprite(QQuick3DTexture *sprite);
void setSpriteSequence(QQuick3DParticleSpriteSequence *spriteSequence);
void setBillboard(bool billboard);
void setParticleScale(float scale);
void setColorTable(QQuick3DTexture *colorTable);
void setOffsetX(float value);
void setOffsetY(float value);
Q_REVISION(6, 4) void setCastsReflections(bool castsReflections);
Q_SIGNALS:
void blendModeChanged();
void spriteChanged();
void spriteSequenceChanged();
void billboardChanged();
void particleScaleChanged();
void colorTableChanged();
Q_REVISION(6, 3) void lightsChanged();
Q_REVISION(6, 3) void offsetXChanged();
Q_REVISION(6, 3) void offsetYChanged();
Q_REVISION(6, 4) void castsReflectionsChanged();
protected:
void itemChange(ItemChange, const ItemChangeData &) override;
void reset() override;
void componentComplete() override;
int nextCurrentIndex(const QQuick3DParticleEmitter *emitter) override;
virtual void setParticleData(int particleIndex,
const QVector3D &position,
const QVector3D &rotation,
const QVector4D &color,
float size, float age,
float animationFrame);
virtual void resetParticleData(int particleIndex);
virtual void commitParticles(float);
void setDepthBias(float bias) override
{
QQuick3DParticle::setDepthBias(bias);
markNodesDirty();
}
private Q_SLOTS:
void onLightDestroyed(QObject *object);
public:
friend class QQuick3DParticleSystem;
friend class QQuick3DParticleEmitter;
friend class QQuick3DParticleSpriteSequence;
enum FeatureLevel
{
Simple = 0,
Mapped,
Animated,
SimpleVLight,
MappedVLight,
AnimatedVLight
};
struct SpriteParticleData
{
QVector3D position;
QVector3D rotation;
QVector4D color;
float size = 0.0f;
float age = 0.0f;
float animationFrame = -1.0f;
int emitterIndex = -1;
};
class ParticleUpdateNode : public QQuick3DNode
{
public:
ParticleUpdateNode(QQuick3DNode *parent = nullptr)
: QQuick3DNode(parent)
{
}
QSSGRenderGraphObject *updateSpatialNode(QSSGRenderGraphObject *node) override;
QQuick3DParticleSpriteParticle *m_particle = nullptr;
bool m_nodeDirty = true;
};
friend class ParticleUpdateNode;
struct PerEmitterData
{
ParticleUpdateNode *particleUpdateNode = nullptr;
int particleCount = 0;
int emitterIndex = -1;
const QQuick3DParticleEmitter *emitter = nullptr;
};
PerEmitterData &perEmitterData(const QQuick3DNode *updateNode);
PerEmitterData &perEmitterData(int emitterIndex);
QSSGRenderGraphObject *updateParticleNode(const ParticleUpdateNode *updateNode, QSSGRenderGraphObject *node);
protected:
virtual void handleMaxAmountChanged(int amount);
virtual void handleSystemChanged(QQuick3DParticleSystem *system);
void updateNodes();
void deleteNodes();
void markNodesDirty();
void updateNodeLayers() override;
QMap<const QQuick3DParticleEmitter *, PerEmitterData> m_perEmitterData;
QVector<SpriteParticleData> m_spriteParticleData;
int m_nextEmitterIndex = 0;
FeatureLevel m_featureLevel = FeatureLevel::Simple;
private:
static QSSGRenderParticles::FeatureLevel mapFeatureLevel(QQuick3DParticleSpriteParticle::FeatureLevel level);
void updateParticleBuffer(ParticleUpdateNode *updateNode, QSSGRenderGraphObject *node);
void updateAnimatedParticleBuffer(ParticleUpdateNode *updateNode, QSSGRenderGraphObject *node);
void updateSceneManager(QQuick3DSceneManager *window);
// Call this whenever features which may affect the level change
void updateFeatureLevel();
std::array<QMetaObject::Connection, 3> m_connections;
PerEmitterData n_noPerEmitterData;
BlendMode m_blendMode = SourceOver;
QQuick3DTexture *m_sprite = nullptr;
QQuick3DTexture *m_colorTable = nullptr;
float m_particleScale = 5.0f;
bool m_billboard = false;
bool m_useAnimatedParticle = false;
// Lights
Q_REVISION(6, 3) static void qmlAppendLight(QQmlListProperty<QQuick3DAbstractLight> *list, QQuick3DAbstractLight *light);
Q_REVISION(6, 3) static QQuick3DAbstractLight *qmlLightAt(QQmlListProperty<QQuick3DAbstractLight> *list, qsizetype index);
Q_REVISION(6, 3) static qsizetype qmlLightsCount(QQmlListProperty<QQuick3DAbstractLight> *list);
Q_REVISION(6, 3) static void qmlClearLights(QQmlListProperty<QQuick3DAbstractLight> *list);
QVector<QQuick3DAbstractLight *> m_lights;
QVector3D m_offset = {};
bool m_castsReflections = true;
};
QT_END_NAMESPACE
#endif