Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
randominstancing.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
5#include <QRandomGenerator>
6#include <QObject>
7
9
185
189
191{
192 if (instanceCount == m_randomCount)
193 return;
194 m_randomCount = instanceCount;
195 m_dirty = true;
196 markDirty();
197}
198
200{
201 if (m_randomSeed == randomSeed)
202 return;
203
204 m_randomSeed = randomSeed;
206 m_dirty = true;
207 markDirty();
208}
209
211{
212 if (m_position == position)
213 return;
214
215 if (m_position)
216 disconnect(m_position, &QQuick3DInstanceRange::changed, this, &QQuick3DRandomInstancing::handleChange);
217 m_position = position;
219 m_dirty = true;
220 markDirty();
221 if (m_position) {
222 connect(m_position, &QQuick3DInstanceRange::changed, this, &QQuick3DRandomInstancing::handleChange);
223 connect(m_position, &QObject::destroyed, this, [this](QObject *obj){ if (obj == m_position) m_position = nullptr; });
224 }
225}
226
228{
229 if (m_scale == scale)
230 return;
231
232 if (m_scale)
233 disconnect(m_scale, &QQuick3DInstanceRange::changed, this, &QQuick3DRandomInstancing::handleChange);
234 m_scale = scale;
236 m_dirty = true;
237 markDirty();
238 if (m_scale) {
239 connect(m_scale, &QQuick3DInstanceRange::changed, this, &QQuick3DRandomInstancing::handleChange);
240 connect(m_scale, &QObject::destroyed, this, [this](QObject *obj){ if (obj == m_scale) m_scale = nullptr; });
241 }
242}
243
245{
246 if (m_rotation == rotation)
247 return;
248
249 if (m_rotation)
250 disconnect(m_rotation, &QQuick3DInstanceRange::changed, this, &QQuick3DRandomInstancing::handleChange);
251 m_rotation = rotation;
253 m_dirty = true;
254 markDirty();
255 if (m_rotation) {
256 connect(m_rotation, &QQuick3DInstanceRange::changed, this, &QQuick3DRandomInstancing::handleChange);
257 connect(m_rotation, &QObject::destroyed, this, [this](QObject *obj){ if (obj == m_rotation) m_rotation = nullptr; });
258 }
259}
260
262{
263 if (m_color == color)
264 return;
265
266 if (m_color)
267 disconnect(m_color, &QQuick3DInstanceRange::changed, this, &QQuick3DRandomInstancing::handleChange);
268 m_color = color;
270 m_dirty = true;
271 markDirty();
272 if (m_color) {
273 connect(m_color, &QQuick3DInstanceRange::changed, this, &QQuick3DRandomInstancing::handleChange);
274 connect(m_color, &QObject::destroyed, this, [this](QObject *obj){ if (obj == m_color) m_color = nullptr; });
275 }
276
277}
278
280{
281 if (m_customData == customData)
282 return;
283
284 if (m_customData)
285 disconnect(m_customData, &QQuick3DInstanceRange::changed, this, &QQuick3DRandomInstancing::handleChange);
286 m_customData = customData;
288 m_dirty = true;
289 markDirty();
290 if (m_customData) {
291 connect(m_customData, &QQuick3DInstanceRange::changed, this, &QQuick3DRandomInstancing::handleChange);
292 connect(m_customData, &QObject::destroyed, this, [this](QObject *obj){ if (obj == m_customData) m_customData = nullptr; });
293 }
294}
295
297{
298 if (m_colorModel == colorModel)
299 return;
300 m_colorModel = colorModel;
302 m_dirty = true;
303 markDirty();
304}
305
306void QQuick3DRandomInstancing::handleChange()
307{
308 m_dirty = true;
309 markDirty();
310}
311
312static inline float genRandom(float from, float to, QRandomGenerator *rgen)
313{
314 float c = rgen->bounded(1.0);
315 return from + c * (to - from);
316}
317
318static QVector3D genRandom(const QVector3D &from, const QVector3D &to, bool proportional, QRandomGenerator *rgen)
319{
320 if (proportional) {
321 float c = rgen->bounded(1.0);
322 return from + c * (to - from);
323 }
324 return { genRandom(from.x(), to.x(), rgen), genRandom(from.y(), to.y(), rgen), genRandom(from.z(), to.z(), rgen) };
325}
326
327static QVector4D genRandom(const QVector4D &from, const QVector4D &to, bool proportional, QRandomGenerator *rgen)
328{
329 if (proportional) {
330 float c = rgen->bounded(1.0);
331 return from + c * (to - from);
332 }
333 return { genRandom(from.x(), to.x(), rgen), genRandom(from.y(), to.y(), rgen), genRandom(from.z(), to.z(), rgen), genRandom(from.w(), to.w(), rgen) };
334}
335
336static QColor genRandom(const QColor &from, const QColor &to, bool proportional, QQuick3DRandomInstancing::ColorModel colorModel, QRandomGenerator *rgen)
337{
338 QVector4D v1, v2;
339 switch (colorModel) {
341 from.getHslF(&v1[0], &v1[1], &v1[2], &v1[3]);
342 to.getHslF(&v2[0], &v2[1], &v2[2], &v2[3]);
343 break;
345 from.getHsvF(&v1[0], &v1[1], &v1[2], &v1[3]);
346 to.getHsvF(&v2[0], &v2[1], &v2[2], &v2[3]);
347 break;
349 default:
350 from.getRgbF(&v1[0], &v1[1], &v1[2], &v1[3]);
351 to.getRgbF(&v2[0], &v2[1], &v2[2], &v2[3]);
352 break;
353 }
354 QVector4D r = genRandom(v1, v2, proportional, rgen);
355
356 switch (colorModel) {
358 return QColor::fromHslF(r[0], r[1], r[2], r[3]);
359 break;
361 return QColor::fromHsvF(r[0], r[1], r[2], r[3]);
362 break;
364 default:
365 return QColor::fromRgbF(r[0], r[1], r[2], r[3]);
366 }
367}
368
370{
371 if (m_dirty)
372 generateInstanceTable();
373 if (instanceCount)
374 *instanceCount = m_randomCount;
375 return m_instanceData;
376}
377
378void QQuick3DRandomInstancing::generateInstanceTable()
379{
380 m_dirty = false;
381 const int count = m_randomCount;
382
383 QRandomGenerator rgen(m_randomSeed);
384 if (m_randomSeed == -1)
385 rgen.seed(QRandomGenerator::global()->generate());
386
387 qsizetype tableSize = count * sizeof(InstanceTableEntry);
388 m_instanceData.resize(tableSize);
389
390 //qDebug() << "generating" << count << "instances, for total size" << tableSize;
391 auto *array = reinterpret_cast<InstanceTableEntry*>(m_instanceData.data());
392 for (int i = 0; i < count; ++i) {
394 QVector3D scale{1, 1, 1};
395 QVector3D eulerRotation;
398 if (m_position)
399 pos = genRandom(m_position->from().value<QVector3D>(), m_position->to().value<QVector3D>(), m_position->proportional(), &rgen);
400 if (m_scale)
401 scale = genRandom(m_scale->from().value<QVector3D>(), m_scale->to().value<QVector3D>(), m_scale->proportional(), &rgen);
402 if (m_rotation) //TODO: quaternion rotation???
403 eulerRotation = genRandom(m_rotation->from().value<QVector3D>(), m_rotation->to().value<QVector3D>(), m_rotation->proportional(), &rgen);
404 if (m_color)
405 color = genRandom(m_color->from().value<QColor>(), m_color->to().value<QColor>(), m_color->proportional(), m_colorModel, &rgen);
406 if (m_customData)
407 customData = genRandom(m_customData->from().value<QVector4D>(), m_customData->to().value<QVector4D>(), m_customData->proportional(), &rgen);
408
409 array[i] = calculateTableEntry(pos, scale, eulerRotation, color, customData);
410 }
411}
412
418
420{
421 if (m_from == from)
422 return;
423
424 m_from = from;
426 emit changed();
427}
428
430{
431 if (m_to == to)
432 return;
433
434 m_to = to;
435 emit toChanged();
436 emit changed();
437}
438
440{
441 if (m_proportional == proportional)
442 return;
443
444 m_proportional = proportional;
446 emit changed();
447}
448
\inmodule QtCore
Definition qbytearray.h:57
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
Definition qbytearray.h:611
void resize(qsizetype size)
Sets the size of the byte array to size bytes.
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
void getRgbF(float *r, float *g, float *b, float *a=nullptr) const
Sets the contents pointed to by r, g, b, and a, to the red, green, blue, and alpha-channel (transpare...
Definition qcolor.cpp:1252
static QColor fromHslF(float h, float s, float l, float a=1.0)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qcolor.cpp:2594
void getHslF(float *h, float *s, float *l, float *a=nullptr) const
Definition qcolor.cpp:1127
void getHsvF(float *h, float *s, float *v, float *a=nullptr) const
Sets the contents pointed to by h, s, v, and a, to the hue, saturation, value, and alpha-channel (tra...
Definition qcolor.cpp:1017
static QColor fromHsvF(float h, float s, float v, float a=1.0)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qcolor.cpp:2530
static QColor fromRgbF(float r, float g, float b, float a=1.0)
Static convenience function that returns a QColor constructed from the RGB color values,...
Definition qcolor.cpp:2427
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
void setProportional(bool proportional)
QQuick3DInstanceRange(QQuick3DObject *parent=nullptr)
void setFrom(QVariant from)
\inmodule QtQuick3D \inherits QQuick3DObject
void markDirty()
Mark that the instance data has changed and must be uploaded again.
static InstanceTableEntry calculateTableEntry(const QVector3D &position, const QVector3D &scale, const QVector3D &eulerRotation, const QColor &color, const QVector4D &customData={})
Converts the position scale eulerRotation color and customData to the instance table format expected ...
\qmltype Object3D \inqmlmodule QtQuick3D \instantiates QQuick3DObject \inherits QtObject
void setRandomSeed(int randomSeed)
void setColor(QQuick3DInstanceRange *color)
void setCustomData(QQuick3DInstanceRange *customData)
QByteArray getInstanceBuffer(int *instanceCount) override
Implement this function to return the contents of the instance table.
void setInstanceCount(int instanceCount)
QQuick3DInstanceRange * color
void setRotation(QQuick3DInstanceRange *rotation)
void setColorModel(ColorModel colorModel)
QQuick3DInstanceRange * rotation
QQuick3DInstanceRange * scale
void setPosition(QQuick3DInstanceRange *position)
void setScale(QQuick3DInstanceRange *scale)
QQuick3DInstanceRange * position
QQuick3DInstanceRange * customData
QQuick3DRandomInstancing(QQuick3DObject *parent=nullptr)
\qmltype InstanceRange \inherits Object3D \inqmlmodule QtQuick3D.Helpers
\inmodule QtCore \reentrant
Definition qrandom.h:21
static Q_DECL_CONST_FUNCTION QRandomGenerator * global()
\threadsafe
Definition qrandom.h:275
\inmodule QtCore
Definition qvariant.h:65
T value() const &
Definition qvariant.h:516
The QVector3D class represents a vector or vertex in 3D space.
Definition qvectornd.h:171
constexpr float y() const noexcept
Returns the y coordinate of this point.
Definition qvectornd.h:671
constexpr float x() const noexcept
Returns the x coordinate of this point.
Definition qvectornd.h:670
constexpr float z() const noexcept
Returns the z coordinate of this point.
Definition qvectornd.h:672
The QVector4D class represents a vector or vertex in 4D space.
Definition qvectornd.h:330
constexpr float x() const noexcept
Returns the x coordinate of this point.
Definition qvectornd.h:878
constexpr float w() const noexcept
Returns the w coordinate of this point.
Definition qvectornd.h:881
constexpr float y() const noexcept
Returns the y coordinate of this point.
Definition qvectornd.h:879
constexpr float z() const noexcept
Returns the z coordinate of this point.
Definition qvectornd.h:880
Combined button and popup list for selecting options.
@ white
Definition qnamespace.h:31
static int instanceCount
GLint GLfloat GLfloat GLfloat v2
GLboolean r
[2]
GLenum GLenum GLsizei count
GLuint color
[2]
GLint GLfloat GLfloat v1
GLhandleARB obj
[2]
const GLubyte * c
GLenum array
GLenum GLenum GLenum GLenum GLenum scale
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
#define v1
#define emit
ptrdiff_t qsizetype
Definition qtypes.h:165
static float genRandom(float from, float to, QRandomGenerator *rgen)
myObject disconnect()
[26]