7#include <QtQuick3DRuntimeRender/private/qssgrenderreflectionprobe_p.h>
8#include <QtQuick3DUtils/private/qssgutils_p.h>
13
14
15
16
17
18
19
20
21
22
23
25QQuick3DReflectionProbe::QQuick3DReflectionProbe(QQuick3DNode *parent)
26 : QQuick3DNode(*(
new QQuick3DNodePrivate(QQuick3DNodePrivate::Type::ReflectionProbe)), parent)
28 QObject::connect(
this, &QQuick3DReflectionProbe::scenePositionChanged,
this, &QQuick3DReflectionProbe::updateDebugView);
31void QQuick3DReflectionProbe::itemChange(QQuick3DObject::ItemChange change,
32 const QQuick3DObject::ItemChangeData &value)
34 if (change == QQuick3DObject::ItemSceneChange)
35 updateSceneManager(value.sceneManager);
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57QQuick3DReflectionProbe::ReflectionQuality QQuick3DReflectionProbe::quality()
const
63
64
65
66
67QColor QQuick3DReflectionProbe::clearColor()
const
73
74
75
76
77
78
79
80
81
82
83
84
85
86QQuick3DReflectionProbe::ReflectionRefreshMode QQuick3DReflectionProbe::refreshMode()
const
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115QQuick3DReflectionProbe::ReflectionTimeSlicing QQuick3DReflectionProbe::timeSlicing()
const
117 return m_timeSlicing;
121
122
123
124
125
126
127
128
129
130bool QQuick3DReflectionProbe::parallaxCorrection()
const
132 return m_parallaxCorrection;
136
137
138
139
140
141
142
143
144
145
146QVector3D QQuick3DReflectionProbe::boxSize()
const
152
153
154
155
156
157bool QQuick3DReflectionProbe::debugView()
const
163
164
165
166
167
168
169
170
171
172
173
174
175QVector3D QQuick3DReflectionProbe::boxOffset()
const
181
182
183
184
185
186
187
188
189QQuick3DCubeMapTexture *QQuick3DReflectionProbe::texture()
const
195
196
197
198
199
200void QQuick3DReflectionProbe::scheduleUpdate()
202 m_dirtyFlags.setFlag(DirtyFlag::RefreshModeDirty);
206void QQuick3DReflectionProbe::setQuality(QQuick3DReflectionProbe::ReflectionQuality reflectionQuality)
208 if (m_quality == reflectionQuality)
211 m_quality = reflectionQuality;
212 m_dirtyFlags.setFlag(DirtyFlag::QualityDirty);
213 emit qualityChanged();
217void QQuick3DReflectionProbe::setClearColor(
const QColor &clearColor)
219 if (m_clearColor == clearColor)
221 m_clearColor = clearColor;
222 m_dirtyFlags.setFlag(DirtyFlag::ClearColorDirty);
223 emit clearColorChanged();
227void QQuick3DReflectionProbe::setRefreshMode(ReflectionRefreshMode newRefreshMode)
229 if (m_refreshMode == newRefreshMode)
231 m_refreshMode = newRefreshMode;
232 m_dirtyFlags.setFlag(DirtyFlag::RefreshModeDirty);
233 emit refreshModeChanged();
237void QQuick3DReflectionProbe::setTimeSlicing(ReflectionTimeSlicing newTimeSlicing)
239 if (m_timeSlicing == newTimeSlicing)
241 m_timeSlicing = newTimeSlicing;
242 m_dirtyFlags.setFlag(DirtyFlag::TimeSlicingDirty);
243 emit timeSlicingChanged();
247void QQuick3DReflectionProbe::setParallaxCorrection(
bool parallaxCorrection)
249 if (m_parallaxCorrection == parallaxCorrection)
251 m_parallaxCorrection = parallaxCorrection;
252 m_dirtyFlags.setFlag(DirtyFlag::ParallaxCorrectionDirty);
253 emit parallaxCorrectionChanged();
257void QQuick3DReflectionProbe::setBoxSize(
const QVector3D &boxSize)
259 if (m_boxSize == boxSize)
262 m_dirtyFlags.setFlag(DirtyFlag::BoxDirty);
263 emit boxSizeChanged();
269void QQuick3DReflectionProbe::setDebugView(
bool debugView)
271 if (m_debugView == debugView)
273 m_debugView = debugView;
274 emit debugViewChanged();
279void QQuick3DReflectionProbe::setBoxOffset(
const QVector3D &boxOffset)
281 if (m_boxOffset == boxOffset)
283 m_boxOffset = boxOffset;
284 m_dirtyFlags.setFlag(DirtyFlag::BoxDirty);
285 emit boxOffsetChanged();
291void QQuick3DReflectionProbe::setTexture(QQuick3DCubeMapTexture *newTexture)
293 if (m_texture == newTexture)
295 QQuick3DObjectPrivate::attachWatcher(
this, &QQuick3DReflectionProbe::setTexture, newTexture, m_texture);
296 m_texture = newTexture;
297 m_dirtyFlags.setFlag(DirtyFlag::TextureDirty);
298 emit textureChanged();
302QSSGRenderGraphObject *QQuick3DReflectionProbe::updateSpatialNode(QSSGRenderGraphObject *node)
306 node =
new QSSGRenderReflectionProbe();
309 QQuick3DNode::updateSpatialNode(node);
311 QSSGRenderReflectionProbe *probe =
static_cast<QSSGRenderReflectionProbe *>(node);
313 if (m_dirtyFlags.testFlag(DirtyFlag::QualityDirty)) {
314 m_dirtyFlags.setFlag(DirtyFlag::QualityDirty,
false);
315 probe->reflectionMapRes = mapToReflectionResolution(m_quality);
318 if (m_dirtyFlags.testFlag(DirtyFlag::ClearColorDirty)) {
319 m_dirtyFlags.setFlag(DirtyFlag::ClearColorDirty,
false);
320 probe->clearColor = m_clearColor;
323 if (m_dirtyFlags.testFlag(DirtyFlag::RefreshModeDirty)) {
324 m_dirtyFlags.setFlag(DirtyFlag::RefreshModeDirty,
false);
325 switch (m_refreshMode) {
326 case ReflectionRefreshMode::FirstFrame:
327 probe->refreshMode = QSSGRenderReflectionProbe::ReflectionRefreshMode::FirstFrame;
329 case ReflectionRefreshMode::EveryFrame:
330 probe->refreshMode = QSSGRenderReflectionProbe::ReflectionRefreshMode::EveryFrame;
333 probe->hasScheduledUpdate =
true;
336 if (m_dirtyFlags.testFlag(DirtyFlag::TimeSlicingDirty)) {
337 m_dirtyFlags.setFlag(DirtyFlag::TimeSlicingDirty,
false);
338 switch (m_timeSlicing) {
339 case ReflectionTimeSlicing::None:
340 probe->timeSlicing = QSSGRenderReflectionProbe::ReflectionTimeSlicing::None;
342 case ReflectionTimeSlicing::AllFacesAtOnce:
343 probe->timeSlicing = QSSGRenderReflectionProbe::ReflectionTimeSlicing::AllFacesAtOnce;
345 case ReflectionTimeSlicing::IndividualFaces:
346 probe->timeSlicing = QSSGRenderReflectionProbe::ReflectionTimeSlicing::IndividualFaces;
351 if (m_dirtyFlags.testFlag(DirtyFlag::ParallaxCorrectionDirty)) {
352 m_dirtyFlags.setFlag(DirtyFlag::ParallaxCorrectionDirty,
false);
353 probe->parallaxCorrection = m_parallaxCorrection;
356 if (m_dirtyFlags.testFlag(DirtyFlag::BoxDirty)) {
357 m_dirtyFlags.setFlag(DirtyFlag::BoxDirty,
false);
358 probe->boxSize = m_boxSize;
359 probe->boxOffset = m_boxOffset;
362 if (m_dirtyFlags.testFlag(DirtyFlag::TextureDirty)) {
363 m_dirtyFlags.setFlag(DirtyFlag::TextureDirty,
false);
365 probe->texture = m_texture->getRenderImage();
367 probe->texture =
nullptr;
373void QQuick3DReflectionProbe::markAllDirty()
375 m_dirtyFlags = QQuick3DReflectionProbe::AllDirty;
377 QQuick3DNode::markAllDirty();
380void QQuick3DReflectionProbe::findSceneView()
383 if (m_sceneView !=
nullptr)
386 QObject *parent =
this;
387 while (parent->parent() !=
nullptr) {
388 parent = parent->parent();
392 QList<QObject *> queue;
393 queue.append(parent);
394 while (!queue.empty()) {
395 auto node = queue.takeFirst();
396 if (
auto converted = qobject_cast<QQuick3DViewport *>(node); converted !=
nullptr) {
397 m_sceneView = converted;
400 queue.append(node->children());
404void QQuick3DReflectionProbe::createDebugView()
410 qWarning() <<
"ReflectionProbe: Can not create debug view. A root View3D could not be found.";
414 if (!m_debugViewGeometry)
415 m_debugViewGeometry =
new QQuick3DGeometry(
this);
417 m_debugViewGeometry->clear();
418 m_debugViewGeometry->addAttribute(QQuick3DGeometry::Attribute::PositionSemantic, 0,
419 QQuick3DGeometry::Attribute::ComponentType::F32Type);
420 m_debugViewGeometry->setStride(12);
421 m_debugViewGeometry->setPrimitiveType(QQuick3DGeometry::PrimitiveType::Lines);
423 QVector<QVector3D> m_vertices;
425 m_vertices.append(QVector3D(-0.5, -0.5, 0.5));
426 m_vertices.append(QVector3D(0.5, -0.5, 0.5));
428 m_vertices.append(QVector3D(0.5, -0.5, 0.5));
429 m_vertices.append(QVector3D(0.5, 0.5, 0.5));
431 m_vertices.append(QVector3D(0.5, 0.5, 0.5));
432 m_vertices.append(QVector3D(-0.5, 0.5, 0.5));
434 m_vertices.append(QVector3D(-0.5, 0.5, 0.5));
435 m_vertices.append(QVector3D(-0.5, -0.5, 0.5));
437 m_vertices.append(QVector3D(-0.5, -0.5, -0.5));
438 m_vertices.append(QVector3D(0.5, -0.5, -0.5));
440 m_vertices.append(QVector3D(0.5, -0.5, -0.5));
441 m_vertices.append(QVector3D(0.5, 0.5, -0.5));
443 m_vertices.append(QVector3D(0.5, 0.5, -0.5));
444 m_vertices.append(QVector3D(-0.5, 0.5, -0.5));
446 m_vertices.append(QVector3D(-0.5, 0.5, -0.5));
447 m_vertices.append(QVector3D(-0.5, -0.5, -0.5));
449 m_vertices.append(QVector3D(-0.5, 0.5, -0.5));
450 m_vertices.append(QVector3D(-0.5, 0.5, 0.5));
452 m_vertices.append(QVector3D(0.5, 0.5, -0.5));
453 m_vertices.append(QVector3D(0.5, 0.5, 0.5));
455 m_vertices.append(QVector3D(-0.5, -0.5, -0.5));
456 m_vertices.append(QVector3D(-0.5, -0.5, 0.5));
458 m_vertices.append(QVector3D(0.5, -0.5, -0.5));
459 m_vertices.append(QVector3D(0.5, -0.5, 0.5));
461 QByteArray vertexData;
462 vertexData.resize(m_vertices.size() * 3 *
sizeof(
float));
463 float *data =
reinterpret_cast<
float *>(vertexData.data());
464 for (
int i = 0; i < m_vertices.size(); i++) {
465 data[0] = m_vertices[i].x();
466 data[1] = m_vertices[i].y();
467 data[2] = m_vertices[i].z();
471 m_debugViewGeometry->setVertexData(vertexData);
472 m_debugViewGeometry->update();
474 if (!m_debugViewModel) {
475 m_debugViewModel =
new QQuick3DModel();
476 m_debugViewModel->setParentItem(m_sceneView->scene());
477 m_debugViewModel->setParent(
this);
478 m_debugViewModel->setCastsShadows(
false);
479 m_debugViewModel->setCastsReflections(
false);
480 m_debugViewModel->setGeometry(m_debugViewGeometry);
483 if (!m_debugViewMaterial) {
484 m_debugViewMaterial =
new QQuick3DDefaultMaterial();
485 m_debugViewMaterial->setParentItem(m_debugViewModel);
486 m_debugViewMaterial->setParent(m_debugViewModel);
487 m_debugViewMaterial->setDiffuseColor(QColor(3, 252, 219));
488 m_debugViewMaterial->setLighting(QQuick3DDefaultMaterial::NoLighting);
489 m_debugViewMaterial->setCullMode(QQuick3DMaterial::NoCulling);
490 QQmlListReference materialsRef(m_debugViewModel,
"materials");
491 materialsRef.append(m_debugViewMaterial);
494 if (m_debugViewModel) {
495 delete m_debugViewModel;
496 m_debugViewModel =
nullptr;
497 m_debugViewMaterial =
nullptr;
500 if (m_debugViewGeometry) {
501 delete m_debugViewGeometry;
502 m_debugViewGeometry =
nullptr;
507void QQuick3DReflectionProbe::updateDebugView()
509 if (m_debugViewModel) {
510 m_debugViewModel->setPosition(scenePosition() + m_boxOffset);
511 m_debugViewModel->setScale(m_boxSize);
515quint32 QQuick3DReflectionProbe::mapToReflectionResolution(ReflectionQuality quality)
518 case ReflectionQuality::Low:
520 case ReflectionQuality::Medium:
522 case ReflectionQuality::High:
524 case ReflectionQuality::VeryHigh:
532void QQuick3DReflectionProbe::updateSceneManager(QQuick3DSceneManager *sceneManager)
536 QQuick3DObjectPrivate::refSceneManager(m_texture, *sceneManager);
538 QQuick3DObjectPrivate::derefSceneManager(m_texture);