9#include <QtQuick3DRuntimeRender/private/qssgrenderreflectionprobe_p.h>
10#include <QtQuick3DUtils/private/qssgutils_p.h>
15
16
17
18
19
20
21
22
23
24
25
27QQuick3DReflectionProbe::QQuick3DReflectionProbe(QQuick3DNode *parent)
28 : QQuick3DNode(*(
new QQuick3DNodePrivate(QQuick3DNodePrivate::Type::ReflectionProbe)), parent)
30 QObject::connect(
this, &QQuick3DReflectionProbe::scenePositionChanged,
this, &QQuick3DReflectionProbe::updateDebugView);
33void QQuick3DReflectionProbe::itemChange(QQuick3DObject::ItemChange change,
34 const QQuick3DObject::ItemChangeData &value)
36 if (change == QQuick3DObject::ItemSceneChange)
37 updateSceneManager(value.sceneManager);
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59QQuick3DReflectionProbe::ReflectionQuality QQuick3DReflectionProbe::quality()
const
65
66
67
68
69QColor QQuick3DReflectionProbe::clearColor()
const
75
76
77
78
79
80
81
82
83
84
85
86
87
88QQuick3DReflectionProbe::ReflectionRefreshMode QQuick3DReflectionProbe::refreshMode()
const
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117QQuick3DReflectionProbe::ReflectionTimeSlicing QQuick3DReflectionProbe::timeSlicing()
const
119 return m_timeSlicing;
123
124
125
126
127
128
129
130
131
132bool QQuick3DReflectionProbe::parallaxCorrection()
const
134 return m_parallaxCorrection;
138
139
140
141
142
143
144
145
146
147
148QVector3D QQuick3DReflectionProbe::boxSize()
const
154
155
156
157
158
159bool QQuick3DReflectionProbe::debugView()
const
165
166
167
168
169
170
171
172
173
174
175
176
177QVector3D QQuick3DReflectionProbe::boxOffset()
const
183
184
185
186
187
188
189
190
191QQuick3DCubeMapTexture *QQuick3DReflectionProbe::texture()
const
197
198
199
200
201
202void QQuick3DReflectionProbe::scheduleUpdate()
204 m_dirtyFlags.setFlag(DirtyFlag::RefreshModeDirty);
208void QQuick3DReflectionProbe::setQuality(QQuick3DReflectionProbe::ReflectionQuality reflectionQuality)
210 if (m_quality == reflectionQuality)
213 m_quality = reflectionQuality;
214 m_dirtyFlags.setFlag(DirtyFlag::QualityDirty);
215 emit qualityChanged();
219void QQuick3DReflectionProbe::setClearColor(
const QColor &clearColor)
221 if (m_clearColor == clearColor)
223 m_clearColor = clearColor;
224 m_dirtyFlags.setFlag(DirtyFlag::ClearColorDirty);
225 emit clearColorChanged();
229void QQuick3DReflectionProbe::setRefreshMode(ReflectionRefreshMode newRefreshMode)
231 if (m_refreshMode == newRefreshMode)
233 m_refreshMode = newRefreshMode;
234 m_dirtyFlags.setFlag(DirtyFlag::RefreshModeDirty);
235 emit refreshModeChanged();
239void QQuick3DReflectionProbe::setTimeSlicing(ReflectionTimeSlicing newTimeSlicing)
241 if (m_timeSlicing == newTimeSlicing)
243 m_timeSlicing = newTimeSlicing;
244 m_dirtyFlags.setFlag(DirtyFlag::TimeSlicingDirty);
245 emit timeSlicingChanged();
249void QQuick3DReflectionProbe::setParallaxCorrection(
bool parallaxCorrection)
251 if (m_parallaxCorrection == parallaxCorrection)
253 m_parallaxCorrection = parallaxCorrection;
254 m_dirtyFlags.setFlag(DirtyFlag::ParallaxCorrectionDirty);
255 emit parallaxCorrectionChanged();
259void QQuick3DReflectionProbe::setBoxSize(
const QVector3D &boxSize)
261 if (m_boxSize == boxSize)
264 m_dirtyFlags.setFlag(DirtyFlag::BoxDirty);
265 emit boxSizeChanged();
271void QQuick3DReflectionProbe::setDebugView(
bool debugView)
273 if (m_debugView == debugView)
275 m_debugView = debugView;
276 emit debugViewChanged();
281void QQuick3DReflectionProbe::setBoxOffset(
const QVector3D &boxOffset)
283 if (m_boxOffset == boxOffset)
285 m_boxOffset = boxOffset;
286 m_dirtyFlags.setFlag(DirtyFlag::BoxDirty);
287 emit boxOffsetChanged();
293void QQuick3DReflectionProbe::setTexture(QQuick3DCubeMapTexture *newTexture)
295 if (m_texture == newTexture)
297 QQuick3DObjectPrivate::attachWatcher(
this, &QQuick3DReflectionProbe::setTexture, newTexture, m_texture);
298 m_texture = newTexture;
299 m_dirtyFlags.setFlag(DirtyFlag::TextureDirty);
300 emit textureChanged();
304QSSGRenderGraphObject *QQuick3DReflectionProbe::updateSpatialNode(QSSGRenderGraphObject *node)
308 node =
new QSSGRenderReflectionProbe();
311 QQuick3DNode::updateSpatialNode(node);
313 QSSGRenderReflectionProbe *probe =
static_cast<QSSGRenderReflectionProbe *>(node);
315 if (m_dirtyFlags.testFlag(DirtyFlag::QualityDirty)) {
316 m_dirtyFlags.setFlag(DirtyFlag::QualityDirty,
false);
317 probe->reflectionMapRes = mapToReflectionResolution(m_quality);
320 if (m_dirtyFlags.testFlag(DirtyFlag::ClearColorDirty)) {
321 m_dirtyFlags.setFlag(DirtyFlag::ClearColorDirty,
false);
322 probe->clearColor = m_clearColor;
325 if (m_dirtyFlags.testFlag(DirtyFlag::RefreshModeDirty)) {
326 m_dirtyFlags.setFlag(DirtyFlag::RefreshModeDirty,
false);
327 switch (m_refreshMode) {
328 case ReflectionRefreshMode::FirstFrame:
329 probe->refreshMode = QSSGRenderReflectionProbe::ReflectionRefreshMode::FirstFrame;
331 case ReflectionRefreshMode::EveryFrame:
332 probe->refreshMode = QSSGRenderReflectionProbe::ReflectionRefreshMode::EveryFrame;
335 probe->hasScheduledUpdate =
true;
338 if (m_dirtyFlags.testFlag(DirtyFlag::TimeSlicingDirty)) {
339 m_dirtyFlags.setFlag(DirtyFlag::TimeSlicingDirty,
false);
340 switch (m_timeSlicing) {
341 case ReflectionTimeSlicing::None:
342 probe->timeSlicing = QSSGRenderReflectionProbe::ReflectionTimeSlicing::None;
344 case ReflectionTimeSlicing::AllFacesAtOnce:
345 probe->timeSlicing = QSSGRenderReflectionProbe::ReflectionTimeSlicing::AllFacesAtOnce;
347 case ReflectionTimeSlicing::IndividualFaces:
348 probe->timeSlicing = QSSGRenderReflectionProbe::ReflectionTimeSlicing::IndividualFaces;
353 if (m_dirtyFlags.testFlag(DirtyFlag::ParallaxCorrectionDirty)) {
354 m_dirtyFlags.setFlag(DirtyFlag::ParallaxCorrectionDirty,
false);
355 probe->parallaxCorrection = m_parallaxCorrection;
358 if (m_dirtyFlags.testFlag(DirtyFlag::BoxDirty)) {
359 m_dirtyFlags.setFlag(DirtyFlag::BoxDirty,
false);
360 probe->boxSize = m_boxSize;
361 probe->boxOffset = m_boxOffset;
364 if (m_dirtyFlags.testFlag(DirtyFlag::TextureDirty)) {
365 m_dirtyFlags.setFlag(DirtyFlag::TextureDirty,
false);
367 probe->texture = m_texture->getRenderImage();
369 probe->texture =
nullptr;
375void QQuick3DReflectionProbe::markAllDirty()
377 m_dirtyFlags = QQuick3DReflectionProbe::AllDirty;
379 QQuick3DNode::markAllDirty();
382void QQuick3DReflectionProbe::findSceneView()
385 if (m_sceneView !=
nullptr)
388 QObject *parent =
this;
389 while (parent->parent() !=
nullptr) {
390 parent = parent->parent();
394 QList<QObject *> queue;
395 queue.append(parent);
396 while (!queue.empty()) {
397 auto node = queue.takeFirst();
398 if (
auto converted = qobject_cast<QQuick3DViewport *>(node); converted !=
nullptr) {
399 m_sceneView = converted;
402 queue.append(node->children());
406void QQuick3DReflectionProbe::createDebugView()
412 qWarning() <<
"ReflectionProbe: Can not create debug view. A root View3D could not be found.";
416 if (!m_debugViewGeometry)
417 m_debugViewGeometry =
new QQuick3DGeometry(
this);
419 m_debugViewGeometry->clear();
420 m_debugViewGeometry->addAttribute(QQuick3DGeometry::Attribute::PositionSemantic, 0,
421 QQuick3DGeometry::Attribute::ComponentType::F32Type);
422 m_debugViewGeometry->setStride(12);
423 m_debugViewGeometry->setPrimitiveType(QQuick3DGeometry::PrimitiveType::Lines);
425 QVector<QVector3D> m_vertices;
427 m_vertices.append(QVector3D(-0.5, -0.5, 0.5));
428 m_vertices.append(QVector3D(0.5, -0.5, 0.5));
430 m_vertices.append(QVector3D(0.5, -0.5, 0.5));
431 m_vertices.append(QVector3D(0.5, 0.5, 0.5));
433 m_vertices.append(QVector3D(0.5, 0.5, 0.5));
434 m_vertices.append(QVector3D(-0.5, 0.5, 0.5));
436 m_vertices.append(QVector3D(-0.5, 0.5, 0.5));
437 m_vertices.append(QVector3D(-0.5, -0.5, 0.5));
439 m_vertices.append(QVector3D(-0.5, -0.5, -0.5));
440 m_vertices.append(QVector3D(0.5, -0.5, -0.5));
442 m_vertices.append(QVector3D(0.5, -0.5, -0.5));
443 m_vertices.append(QVector3D(0.5, 0.5, -0.5));
445 m_vertices.append(QVector3D(0.5, 0.5, -0.5));
446 m_vertices.append(QVector3D(-0.5, 0.5, -0.5));
448 m_vertices.append(QVector3D(-0.5, 0.5, -0.5));
449 m_vertices.append(QVector3D(-0.5, -0.5, -0.5));
451 m_vertices.append(QVector3D(-0.5, 0.5, -0.5));
452 m_vertices.append(QVector3D(-0.5, 0.5, 0.5));
454 m_vertices.append(QVector3D(0.5, 0.5, -0.5));
455 m_vertices.append(QVector3D(0.5, 0.5, 0.5));
457 m_vertices.append(QVector3D(-0.5, -0.5, -0.5));
458 m_vertices.append(QVector3D(-0.5, -0.5, 0.5));
460 m_vertices.append(QVector3D(0.5, -0.5, -0.5));
461 m_vertices.append(QVector3D(0.5, -0.5, 0.5));
463 QByteArray vertexData;
464 vertexData.resize(m_vertices.size() * 3 *
sizeof(
float));
465 float *data =
reinterpret_cast<
float *>(vertexData.data());
466 for (
int i = 0; i < m_vertices.size(); i++) {
467 data[0] = m_vertices[i].x();
468 data[1] = m_vertices[i].y();
469 data[2] = m_vertices[i].z();
473 m_debugViewGeometry->setVertexData(vertexData);
474 m_debugViewGeometry->update();
476 if (!m_debugViewModel) {
477 m_debugViewModel =
new QQuick3DModel();
478 m_debugViewModel->setParentItem(m_sceneView->scene());
479 m_debugViewModel->setParent(
this);
480 m_debugViewModel->setCastsShadows(
false);
481 m_debugViewModel->setCastsReflections(
false);
482 m_debugViewModel->setGeometry(m_debugViewGeometry);
485 if (!m_debugViewMaterial) {
486 m_debugViewMaterial =
new QQuick3DDefaultMaterial();
487 m_debugViewMaterial->setParentItem(m_debugViewModel);
488 m_debugViewMaterial->setParent(m_debugViewModel);
489 m_debugViewMaterial->setDiffuseColor(QColor(3, 252, 219));
490 m_debugViewMaterial->setLighting(QQuick3DDefaultMaterial::NoLighting);
491 m_debugViewMaterial->setCullMode(QQuick3DMaterial::NoCulling);
492 QQmlListReference materialsRef(m_debugViewModel,
"materials");
493 materialsRef.append(m_debugViewMaterial);
496 if (m_debugViewModel) {
497 delete m_debugViewModel;
498 m_debugViewModel =
nullptr;
499 m_debugViewMaterial =
nullptr;
502 if (m_debugViewGeometry) {
503 delete m_debugViewGeometry;
504 m_debugViewGeometry =
nullptr;
509void QQuick3DReflectionProbe::updateDebugView()
511 if (m_debugViewModel) {
512 m_debugViewModel->setPosition(scenePosition() + m_boxOffset);
513 m_debugViewModel->setScale(m_boxSize);
517quint32 QQuick3DReflectionProbe::mapToReflectionResolution(ReflectionQuality quality)
520 case ReflectionQuality::Low:
522 case ReflectionQuality::Medium:
524 case ReflectionQuality::High:
526 case ReflectionQuality::VeryHigh:
534void QQuick3DReflectionProbe::updateSceneManager(QQuick3DSceneManager *sceneManager)
538 QQuick3DObjectPrivate::refSceneManager(m_texture, *sceneManager);
540 QQuick3DObjectPrivate::derefSceneManager(m_texture);
Combined button and popup list for selecting options.