9#include <QtQml/qqmlcontext.h>
10#include <QtQml/qqmlfile.h>
11#include <QtCore/qfile.h>
16
17
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
53QQuick3DParticleCustomShape::QQuick3DParticleCustomShape(QObject *parent)
54 : QQuick3DParticleAbstractShape(parent)
59
60
61
62
63
64
65
66
67
69QUrl QQuick3DParticleCustomShape::source()
const
75
76
77
78
79
80
81
82bool QQuick3DParticleCustomShape::randomizeData()
const
87void QQuick3DParticleCustomShape::setSource(
const QUrl &source)
89 if (m_source == source)
95 Q_EMIT sourceChanged();
98void QQuick3DParticleCustomShape::setRandomizeData(
bool random)
100 if (m_random == random)
105 m_randomizeDirty =
true;
106 Q_EMIT randomizeDataChanged();
109void QQuick3DParticleCustomShape::loadFromSource()
114 const QQmlContext *context = qmlContext(
this);
115 QString dataFilePath = QQmlFile::urlToLocalFileOrQrc(context ? context->resolvedUrl(m_source) : m_source);
117 QFile dataFile(dataFilePath);
118 if (!dataFile.open(QIODevice::ReadOnly)) {
120 qWarning() <<
"Unable to open file:" << dataFilePath;
123 QCborStreamReader reader(&dataFile);
126 int version = QQuick3DParticleShapeDataUtils::readShapeHeader(reader);
130 qWarning() <<
"Invalid shape data version:" << version;
135 reader.enterContainer();
137 m_center = QVector3D();
138 while (reader.lastError() == QCborError::NoError && reader.hasNext()) {
139 QVector3D pos = QQuick3DParticleShapeDataUtils::readValue(reader, QMetaType::QVector3D).value<QVector3D>();
140 m_positions.append(pos);
143 if (!m_positions.isEmpty())
144 m_center *= 1.0f /
float(m_positions.size());
147 reader.leaveContainer();
150 reader.leaveContainer();
153 m_randomizeDirty =
true;
156void QQuick3DParticleCustomShape::doRandomizeData()
158 if (!m_system || m_positions.isEmpty())
161 auto rand = m_system->rand();
162 int seed = rand->get(0, QPRand::Shape1) *
float(INT_MAX);
163 std::shuffle(m_positions.begin(), m_positions.end(), std::default_random_engine(seed));
165 m_randomizeDirty =
false;
168QVector3D QQuick3DParticleCustomShape::getPosition(
int particleIndex)
170 auto *parent = parentNode();
171 if (!parent || m_positions.isEmpty())
174 if (m_randomizeDirty)
177 int index = particleIndex % m_positions.size();
178 return m_positions.at(index) * parent->scale();
181QVector3D QQuick3DParticleCustomShape::getSurfaceNormal(
int particleIndex)
183 auto *parent = parentNode();
184 if (!parent || m_positions.isEmpty())
187 if (m_randomizeDirty)
190 int index = particleIndex % m_positions.size();
191 return (m_positions.at(index) - m_center).normalized();