11#include <QtQml/qqmlcontext.h>
12#include <QtQml/qqmlfile.h>
13#include <QtCore/qfile.h>
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
55QQuick3DParticleCustomShape::QQuick3DParticleCustomShape(QObject *parent)
56 : QQuick3DParticleAbstractShape(parent)
61
62
63
64
65
66
67
68
69
71QUrl QQuick3DParticleCustomShape::source()
const
77
78
79
80
81
82
83
84bool QQuick3DParticleCustomShape::randomizeData()
const
89void QQuick3DParticleCustomShape::setSource(
const QUrl &source)
91 if (m_source == source)
97 Q_EMIT sourceChanged();
100void QQuick3DParticleCustomShape::setRandomizeData(
bool random)
102 if (m_random == random)
107 m_randomizeDirty =
true;
108 Q_EMIT randomizeDataChanged();
111void QQuick3DParticleCustomShape::loadFromSource()
116 const QQmlContext *context = qmlContext(
this);
117 QString dataFilePath = QQmlFile::urlToLocalFileOrQrc(context ? context->resolvedUrl(m_source) : m_source);
119 QFile dataFile(dataFilePath);
120 if (!dataFile.open(QIODevice::ReadOnly)) {
122 qWarning() <<
"Unable to open file:" << dataFilePath;
125 QCborStreamReader reader(&dataFile);
128 int version = QQuick3DParticleShapeDataUtils::readShapeHeader(reader);
132 qWarning() <<
"Invalid shape data version:" << version;
137 reader.enterContainer();
139 m_center = QVector3D();
140 while (reader.lastError() == QCborError::NoError && reader.hasNext()) {
141 QVector3D pos = QQuick3DParticleShapeDataUtils::readValue(reader, QMetaType::QVector3D).value<QVector3D>();
142 m_positions.append(pos);
145 if (!m_positions.isEmpty())
146 m_center *= 1.0f /
float(m_positions.size());
149 reader.leaveContainer();
152 reader.leaveContainer();
155 m_randomizeDirty =
true;
158void QQuick3DParticleCustomShape::doRandomizeData()
160 if (!m_system || m_positions.isEmpty())
163 auto rand = m_system->rand();
164 int seed = rand->get(0, QPRand::Shape1) *
float(INT_MAX);
165 std::shuffle(m_positions.begin(), m_positions.end(), std::default_random_engine(seed));
167 m_randomizeDirty =
false;
170QVector3D QQuick3DParticleCustomShape::getPosition(
int particleIndex)
172 auto *parent = parentNode();
173 if (!parent || m_positions.isEmpty())
176 if (m_randomizeDirty)
179 int index = particleIndex % m_positions.size();
180 return m_positions.at(index) * parent->scale();
183QVector3D QQuick3DParticleCustomShape::getSurfaceNormal(
int particleIndex)
185 auto *parent = parentNode();
186 if (!parent || m_positions.isEmpty())
189 if (m_randomizeDirty)
192 int index = particleIndex % m_positions.size();
193 return (m_positions.at(index) - m_center).normalized();
Combined button and popup list for selecting options.