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 QQUICK3DPPARTICLESYSTEM_H
#define QQUICK3DPPARTICLESYSTEM_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 <QtQuick3DParticles/qtquick3dparticlesglobal.h>
#include <QtQuick3D/private/qquick3dnode_p.h>
#include <QtQuick3D/private/qquick3ddefaultmaterial_p.h>
#include <QtQuick3D/private/qquick3dprincipledmaterial_p.h>
#include <QtQuick3D/private/qquick3dloader_p.h>
#include <QtQuick3DParticles/private/qquick3dparticlesystemlogging_p.h>
#include <QtQuick3DParticles/private/qquick3dparticlerandomizer_p.h>
#include <QtQuick3DParticles/private/qquick3dparticledata_p.h>
#include <QElapsedTimer>
#include <QVector>
#include <QList>
#include <QHash>
#include <QPointer>
#include <QAbstractAnimation>
#include <QtQml/qqml.h>
#include <QElapsedTimer>
#include <QTimer>
QT_BEGIN_NAMESPACE
class QQuick3DParticleSpriteParticle;
class QQuick3DParticleModelParticle;
class QQuick3DParticleModelBlendParticle;
class QQuick3DParticleEmitter;
class QQuick3DParticleTrailEmitter;
class QQuick3DParticleAffector;
class QQuick3DParticleStatelessAffector;
class QQuick3DParticle;
class QQuick3DParticleSystemAnimation;
class QQuick3DParticleSystemUpdate;
class QQuick3DParticleInstanceTable;
class Q_QUICK3DPARTICLES_EXPORT QQuick3DParticleSystem : public QQuick3DNode
{
Q_OBJECT
Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged)
Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged)
Q_PROPERTY(int startTime READ startTime WRITE setStartTime NOTIFY startTimeChanged)
Q_PROPERTY(int time READ time WRITE setTime NOTIFY timeChanged)
Q_PROPERTY(bool useRandomSeed READ useRandomSeed WRITE setUseRandomSeed NOTIFY useRandomSeedChanged)
Q_PROPERTY(int seed READ seed WRITE setSeed NOTIFY seedChanged)
Q_PROPERTY(bool logging READ logging WRITE setLogging NOTIFY loggingChanged)
Q_PROPERTY(QQuick3DParticleSystemLogging *loggingData READ loggingData NOTIFY loggingDataChanged)
QML_NAMED_ELEMENT(ParticleSystem3D)
QML_ADDED_IN_VERSION(6, 2)
public:
QQuick3DParticleSystem(QQuick3DNode *parent = nullptr);
~QQuick3DParticleSystem() override;
bool isRunning() const;
bool isPaused() const;
int startTime() const;
int time() const;
bool useRandomSeed() const;
int seed() const;
// Return the total amount of particles
int particleCount() const;
bool logging() const;
QQuick3DParticleSystemLogging *loggingData() const;
// Registering of different components into system
void registerParticle(QQuick3DParticle *particle);
void unRegisterParticle(QQuick3DParticle *particle);
void registerParticleEmitter(QQuick3DParticleEmitter* e);
void unRegisterParticleEmitter(QQuick3DParticleEmitter* e);
void registerParticleAffector(QQuick3DParticleAffector* a);
void unRegisterParticleAffector(QQuick3DParticleAffector* a);
void updateCurrentTime(int currentTime);
QPRand *rand();
bool isShared(const QQuick3DParticle *particle) const;
int currentTime() const;
struct TrailEmits {
QQuick3DParticleTrailEmitter *emitter = nullptr;
int amount = 0;
};
Q_INVOKABLE void reset();
public Q_SLOTS:
void setRunning(bool running);
void setPaused(bool paused);
void setStartTime(int startTime);
void setTime(int time);
void setUseRandomSeed(bool randomize);
void setSeed(int seed);
void setLogging(bool logging);
void setEditorTime(int time);
Q_SIGNALS:
void runningChanged();
void pausedChanged();
void timeChanged();
void startTimeChanged();
void useRandomSeedChanged();
void seedChanged();
void loggingChanged();
void loggingDataChanged();
protected:
void componentComplete() override;
private:
void updateLoggingData();
void resetLoggingVariables();
void doSeedRandomization();
void refresh();
void markDirty();
void processModelParticle(QQuick3DParticleModelParticle *modelParticle, const QVector<TrailEmits> &trailEmits, float timeS);
void processSpriteParticle(QQuick3DParticleSpriteParticle *spriteParticle, const QVector<TrailEmits> &trailEmits, float timeS);
void processModelBlendParticle(QQuick3DParticleModelBlendParticle *particle, const QVector<TrailEmits> &trailEmits, float timeS);
void processParticleCommon(QQuick3DParticleDataCurrent &currentData, const QQuick3DParticleData *d, float particleTimeS);
void processParticleFadeInOut(QQuick3DParticleDataCurrent &currentData, const QQuick3DParticle *particle, float particleTimeS, float particleTimeLeftS);
void processParticleAlignment(QQuick3DParticleDataCurrent &currentData, const QQuick3DParticle *particle, const QQuick3DParticleData *d);
static bool isGloballyDisabled();
static bool isEditorModeOn();
private:
friend class QQuick3DParticleEmitter;
friend class QQuick3DParticleTrailEmitter;
friend class QQuick3DParticleSystemUpdate;
friend class QQuick3DParticleSystemAnimation;
friend class QQuick3DParticleModelBlendParticle;
bool m_running;
bool m_paused;
bool m_initialized;
bool m_componentComplete;
// This animation runs the system, progressing time with pause, continue etc.
QQuick3DParticleSystemAnimation *m_animation = nullptr;
// This animation handles system dirty updates and runs always.
// It makes sure that updates are done in sync with other animations and only once per frame.
QQuick3DParticleSystemUpdate *m_updateAnimation = nullptr;
QList<QQuick3DParticle *> m_particles;
QList<QQuick3DParticleEmitter *> m_emitters;
QList<QQuick3DParticleTrailEmitter *> m_trailEmitters;
QList<QQuick3DParticleAffector *> m_affectors;
QMap<QQuick3DParticleAffector *, QMetaObject::Connection> m_connections;
int m_startTime = 0;
// Current time in ms
int m_time = 0;
int m_currentTime = 0;
// This overrides the time when editor mode is on
int m_editorTime = 0;
QElapsedTimer m_perfTimer;
QTimer m_loggingTimer;
qint64 m_timeAnimation = 0;
int m_particlesMax = 0;
int m_particlesUsed = 0;
int m_updates = 0;
bool m_useRandomSeed = true;
int m_seed = 0;
bool m_logging;
QQuick3DParticleSystemLogging *m_loggingData = nullptr;
QPRand m_rand;
int m_particleIdIndex = 0;
};
class QQuick3DParticleSystemAnimation : public QAbstractAnimation
{
Q_OBJECT
public:
QQuick3DParticleSystemAnimation(QQuick3DParticleSystem *system)
: QAbstractAnimation(static_cast<QObject *>(system)), m_system(system)
{ }
protected:
void updateCurrentTime(int t) override
{
// Keep the time property up-to-date
if (!m_system->isEditorModeOn() && !m_system->isGloballyDisabled())
m_system->setTime(t);
m_system->updateCurrentTime(t + m_system->startTime());
}
int duration() const override
{
return -1;
}
private:
QQuick3DParticleSystem *m_system;
};
class QQuick3DParticleSystemUpdate : public QAbstractAnimation
{
Q_OBJECT
public:
QQuick3DParticleSystemUpdate(QQuick3DParticleSystem *system)
: QAbstractAnimation(static_cast<QObject *>(system)), m_system(system)
{ }
void setDirty(bool dirty)
{
m_dirty = dirty;
}
protected:
void updateCurrentTime(int t) override
{
Q_UNUSED(t);
if (m_dirty)
m_system->refresh();
}
int duration() const override
{
return -1;
}
private:
QQuick3DParticleSystem *m_system;
bool m_dirty = false;
};
QT_END_NAMESPACE
#endif // QQUICK3DPPARTICLESYSTEM_H