9#include <QLoggingCategory>
11#include <QtQuick3DUtils/private/qssgassert_p.h>
17Q_DECLARE_LOGGING_CATEGORY(lcQuick3DXr);
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
45QQuick3DXrView::QQuick3DXrView()
46 : m_xrRuntimeInfo(&m_xrManager)
51QQuick3DXrView::~QQuick3DXrView()
53 m_inDestructor =
true;
57
58
59
60
61
62
63
64
65
66
67
68
70QQuick3DXrOrigin *QQuick3DXrView::xrOrigin()
const
76
77
78
80QQuick3DSceneEnvironment *QQuick3DXrView::environment()
const
82 return m_xrManager.m_vrViewport ? m_xrManager.m_vrViewport->environment() :
nullptr;
85QQuick3DViewport *QQuick3DXrView::view3d()
const
87 return m_xrManager.m_vrViewport;
91
92
93
94bool QQuick3DXrView::passthroughEnabled()
const
96 return m_xrManager.isPassthroughEnabled();
100
101
102
104QQuick3DXrRuntimeInfo *QQuick3DXrView::runtimeInfo()
const
106 return &m_xrRuntimeInfo;
109void QQuick3DXrView::setEnvironment(QQuick3DSceneEnvironment *environment)
111 QQuick3DViewport *view = m_xrManager.m_vrViewport;
116 m_pendingSceneEnvironment = environment;
120 auto oldEnvironment = view->environment();
121 if (oldEnvironment == environment)
125 disconnect(oldEnvironment);
127 view->setEnvironment(environment);
132 environment = view->environment();
134 handleClearColorChanged();
137 connect(environment, &QQuick3DSceneEnvironment::backgroundModeChanged,
this, &QQuick3DXrView::handleClearColorChanged);
138 connect(environment, &QQuick3DSceneEnvironment::clearColorChanged,
this, &QQuick3DXrView::handleClearColorChanged);
139 connect(environment, &QQuick3DSceneEnvironment::antialiasingModeChanged,
this, &QQuick3DXrView::handleAAChanged);
140 connect(environment, &QQuick3DSceneEnvironment::antialiasingQualityChanged,
this, &QQuick3DXrView::handleAAChanged);
142 emit environmentChanged(environment);
146
147
148
150bool QQuick3DXrView::passthroughSupported()
const
152 if (!m_xrManager.isValid())
155 return m_xrManager.supportsPassthrough();
158void QQuick3DXrView::setPassthroughEnabled(
bool enable)
160 if (!m_xrManager.isValid()) {
161 qWarning(
"Attempted to set passthrough mode without a valid XR manager");
165 const bool orgPassthroughEnabled = m_xrManager.isPassthroughEnabled();
167 if (!m_xrManager.setPassthroughEnabled(enable)) {
168 qWarning(
"Enabling Passthrough is not supported.");
172 if (orgPassthroughEnabled != m_xrManager.isPassthroughEnabled())
173 emit passthroughEnabledChanged();
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
200QQuick3DXrView::FoveationLevel QQuick3DXrView::fixedFoveation()
const
202 return FoveationLevel(m_xrManager.getFixedFoveationLevel());
205void QQuick3DXrView::setFixedFoveation(FoveationLevel level)
207 const auto orgFoviationLevel = m_xrManager.getFixedFoveationLevel();
208 m_xrManager.setFixedFoveationLevel(QtQuick3DXr::FoveationLevel(level));
209 if (orgFoviationLevel != m_xrManager.getFixedFoveationLevel())
210 emit fixedFoveationChanged();
214
215
216
218bool QQuick3DXrView::isQuitOnSessionEndEnabled()
const
220 return m_quitOnSessionEnd;
223void QQuick3DXrView::setQuitOnSessionEnd(
bool enable)
225 if (m_quitOnSessionEnd == enable)
228 m_quitOnSessionEnd = enable;
229 emit quitOnSessionEndChanged();
232
233
234
236QQuick3DRenderStats *QQuick3DXrView::renderStats()
const
238 return m_xrManager.m_vrViewport ? m_xrManager.m_vrViewport->renderStats() :
nullptr;
241void QQuick3DXrView::updateViewportGeometry()
243 auto contentItem = m_xrManager.m_quickWindow->contentItem();
244 auto viewport = m_xrManager.m_vrViewport;
245 if (viewport->height() != contentItem->height())
246 viewport->setHeight(contentItem->height());
247 if (viewport->width() != contentItem->width())
248 viewport->setWidth(contentItem->width());
249 if (viewport->x() != contentItem->x())
250 viewport->setX(contentItem->x());
251 if (viewport->y() != contentItem->y())
252 viewport->setY(contentItem->y());
255void QQuick3DXrView::handleSessionEnded()
258 if (m_quitOnSessionEnd)
259 QCoreApplication::quit();
262void QQuick3DXrView::handleClearColorChanged()
264 auto env = environment();
267 if (env->backgroundMode() == QQuick3DSceneEnvironment::Color)
268 m_xrManager.m_quickWindow->setColor(env->clearColor());
269 else if (env->backgroundMode() == QQuick3DSceneEnvironment::Transparent)
270 m_xrManager.m_quickWindow->setColor(Qt::transparent);
274void QQuick3DXrView::handleAAChanged()
276 auto env = environment();
278 if (env && env->antialiasingMode() == QQuick3DSceneEnvironment::MSAA) {
279 switch (env->antialiasingQuality()) {
280 case QQuick3DSceneEnvironment::Medium:
283 case QQuick3DSceneEnvironment::High:
286 case QQuick3DSceneEnvironment::VeryHigh:
291 m_xrManager.setSamples(samples);
294bool QQuick3DXrView::init()
296 if (m_isInitialized) {
297 qWarning(
"Already initialized!");
301 connect(&m_xrManager, &QQuick3DXrManager::sessionEnded,
this, &QQuick3DXrView::handleSessionEnded);
302 connect(&m_xrManager, &QQuick3DXrManager::frameReady,
this, &QQuick3DXrView::frameReady);
303 connect(&m_xrManager, &QQuick3DXrManager::referenceSpaceChanged,
this, &QQuick3DXrView::referenceSpaceChanged);
304 connect(&m_xrManager, &QQuick3DXrManager::multiViewRenderingEnabledChanged,
this, &QQuick3DXrView::multiViewRenderingEnabledChanged);
305 connect(&m_xrManager, &QQuick3DXrManager::initialized,
this, &QQuick3DXrView::init, Qt::UniqueConnection);
307 if (!m_xrManager.isReady() && !m_xrManager.initialize()) {
308 qCDebug(lcQuick3DXr,
"Waiting for XR platform to be initialized");
313 if (!m_xrManager.initialize()) {
314 QString errorString = m_xrManager.errorString();
315 if (errorString.isEmpty())
316 errorString = tr(
"Failed to initialize XR platform");
317 qWarning(
"\n%s\n", qPrintable(errorString));
318 QMetaObject::invokeMethod(
this,
"initializeFailed", Qt::QueuedConnection, errorString);
323 QSSG_CHECK_X(m_xrManager.m_vrViewport ==
nullptr,
"View3D already created!");
324 auto viewport =
new QQuick3DViewport(QQuick3DViewport::PrivateInstanceType::XrViewInstance);
325 viewport->setRenderMode(QQuick3DViewport::Underlay);
326 auto contentItem = m_xrManager.m_quickWindow->contentItem();
327 viewport->setParentItem(contentItem);
328 m_xrManager.m_vrViewport = viewport;
329 viewport->setImportScene(
this);
331 contentItem->forceActiveFocus(Qt::MouseFocusReason);
333 connect(contentItem, &QQuickItem::heightChanged,
this, &QQuick3DXrView::updateViewportGeometry);
334 connect(contentItem, &QQuickItem::widthChanged,
this, &QQuick3DXrView::updateViewportGeometry);
335 connect(contentItem, &QQuickItem::xChanged,
this, &QQuick3DXrView::updateViewportGeometry);
336 connect(contentItem, &QQuickItem::yChanged,
this, &QQuick3DXrView::updateViewportGeometry);
338 QQuick3DSceneEnvironment *env = environment();
340 connect(env, &QQuick3DSceneEnvironment::backgroundModeChanged,
this, &QQuick3DXrView::handleClearColorChanged);
341 connect(env, &QQuick3DSceneEnvironment::clearColorChanged,
this, &QQuick3DXrView::handleClearColorChanged);
342 connect(env, &QQuick3DSceneEnvironment::antialiasingModeChanged,
this, &QQuick3DXrView::handleAAChanged);
343 connect(env, &QQuick3DSceneEnvironment::antialiasingQualityChanged,
this, &QQuick3DXrView::handleAAChanged);
347 setEnvironment(m_pendingSceneEnvironment);
348 m_pendingSceneEnvironment =
nullptr;
350 m_xrManager.update();
352 m_isInitialized =
true;
354 return m_isInitialized;
358
359
360
361
362
363
364
365
366
367
368QQuick3DPickResult QQuick3DXrView::rayPick(
const QVector3D &origin,
const QVector3D &direction)
const
370 return m_xrManager.m_vrViewport->rayPick(origin, direction);
374
375
376
377
378
379
380
381
382
383
384
385
386
387QList<QQuick3DPickResult> QQuick3DXrView::rayPickAll(
const QVector3D &origin,
const QVector3D &direction)
const
389 return m_xrManager.m_vrViewport->rayPickAll(origin, direction);
393
394
395
396
397
398
399
400QQuick3DPickResult QQuick3DXrView::rayPick(
const QVector3D &origin,
const QVector3D &direction, QQuick3DModel *model)
const
402 return m_xrManager.m_vrViewport->rayPick(origin, direction, model);
406
407
408
409
410
411
412
414void QQuick3DXrView::setTouchpoint(QQuickItem *target,
const QPointF &position,
int pointId,
bool pressed)
416 view3d()->setTouchpoint(target, position, pointId, pressed);
420struct QQuick3DXrView::XrTouchState
422 QHash<
int, QQuick3DXrItem::TouchState> points;
426
427
428
429
430
431
432
433
434
435
436
437
438
440QVector3D QQuick3DXrView::processTouch(
const QVector3D &pos,
int pointId)
443 if (m_xrItems.isEmpty())
447 m_touchState =
new XrTouchState;
448 QQuick3DXrItem::TouchState &state = m_touchState->points[pointId];
449 state.pointId = pointId;
451 auto *prevTarget = state.target;
452 bool grabbed =
false;
454 grabbed = prevTarget->handleVirtualTouch(
this, pos, &state, &offset);
456 for (
auto *item : std::as_const(m_xrItems)) {
459 if (item != prevTarget)
460 grabbed = item->handleVirtualTouch(
this, pos, &state, &offset);
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
501#define Q_TOUCHPOINT_STATE(prop) { QStringLiteral(#prop), QVariant::fromValue(it->prop) }
502QVariantMap QQuick3DXrView::touchpointState(
int pointId)
const
504 auto constexpr end = QHash<
int, QQuick3DXrItem::TouchState>::const_iterator();
505 auto it = m_touchState ? m_touchState->points.constFind(pointId) : end;
508 return { { QStringLiteral(
"grabbed"), QVariant::fromValue(
false) } };
516#undef Q_TOUCHPOINT_STATE
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
540QQuick3DXrView::ReferenceSpace QQuick3DXrView::referenceSpace()
const
542 return ReferenceSpace(m_xrManager.getReferenceSpace());
545void QQuick3DXrView::setReferenceSpace(ReferenceSpace newReferenceSpace)
547 m_xrManager.setReferenceSpace(QtQuick3DXr::ReferenceSpace(newReferenceSpace));
550bool QQuick3DXrView::depthSubmissionEnabled()
const
552 if (!m_xrManager.isValid()) {
553 qWarning(
"Attempted to check depth submission mode without a valid XR manager");
557 return m_xrManager.isDepthSubmissionEnabled();
561
562
563
564
565
566
567bool QQuick3DXrView::isMultiViewRenderingSupported()
const
569 if (!m_xrManager.isValid())
572 return m_xrManager.isMultiViewRenderingSupported();
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599bool QQuick3DXrView::multiViewRenderingEnabled()
const
601 if (!m_xrManager.isValid())
604 return m_xrManager.isMultiViewRenderingEnabled();
607void QQuick3DXrView::registerXrItem(QQuick3DXrItem *newXrItem)
609 m_xrItems.append(newXrItem);
612void QQuick3DXrView::unregisterXrItem(QQuick3DXrItem *xrItem)
614 m_xrItems.removeAll(xrItem);
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
668void QQuick3DXrView::setDepthSubmissionEnabled(
bool enable)
670 if (!m_xrManager.isValid()) {
671 qWarning(
"Attempted to set depth submission mode without a valid XR manager");
675 const bool orgDepthSubmission = m_xrManager.isDepthSubmissionEnabled();
677 m_xrManager.setDepthSubmissionEnabled(enable);
679 if (orgDepthSubmission != m_xrManager.isDepthSubmissionEnabled())
680 emit depthSubmissionEnabledChanged();
683void QQuick3DXrView::setXROrigin(QQuick3DXrOrigin *newXrOrigin)
685 if (m_xrOrigin == newXrOrigin)
688 QQuick3DObjectPrivate::attachWatcher(
this, &QQuick3DXrView::setXROrigin, newXrOrigin, m_xrOrigin);
690 m_xrOrigin = newXrOrigin;
693 if (m_xrOrigin && !m_xrOrigin->parentItem())
694 m_xrOrigin->setParentItem(
this);
696 m_xrManager.setXROrigin(m_xrOrigin);
698 emit xrOriginChanged();
701QQuick3DViewport *QQuick3DXrViewPrivate::getView3d(QQuick3DXrView *view)
703 QSSG_ASSERT(view !=
nullptr,
return nullptr);
704 return view->view3d();
708
709
710
711
712
715
716
717
718
721
722
723
724
725
#define Q_TOUCHPOINT_STATE(prop)
\qmlmethod object XrView::touchpointState(int pointId)