Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquick3dxrmanager.cpp
Go to the documentation of this file.
1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5
7
8#include <QtCore/QCoreApplication>
9#include <QtCore/QDebug>
10#include <QtCore/qjsonobject.h>
11#include <QtCore/qjsonarray.h>
12
13#include <rhi/qrhi.h>
14
15#include <QtQuick/private/qquickwindow_p.h>
16#include <QtQuick/QQuickRenderControl>
17#include <QtQuick/QQuickRenderTarget>
18#include <QtQuick/QQuickItem>
19
20#include <QtQuick3D/private/qquick3dnode_p.h>
21#include <QtQuick3D/private/qquick3dviewport_p.h>
22
23
24// #include "qquick3dxrcamera_p.h"
26
27#if defined(Q_OS_VISIONOS)
28# include <QtQuick3DXr/private/qquick3dxrmanager_visionos_p.h>
29#else
30# include "openxr/qquick3dxrmanager_openxr_p.h"
31#endif
32
35
37
38Q_DECLARE_LOGGING_CATEGORY(lcQuick3DXr);
39Q_LOGGING_CATEGORY(lcQuick3DXr, "qt.quick3d.xr");
40
41QQuick3DXrManager::QQuick3DXrManager(QObject *parent)
42 : QObject(parent)
43 , d_ptr(new QQuick3DXrManagerPrivate(*this))
44{
45}
46
48{
50
51 // maintain the correct order
52 delete m_vrViewport;
53 delete m_quickWindow;
54 delete m_renderControl;
55 delete m_animationDriver;
56}
57
59{
60 Q_D(const QQuick3DXrManager);
61 return d->isReady();
62}
63
65{
66 Q_D(QQuick3DXrManager);
67
68 QString m_errorString;
69
70 // TODO: Handle visionos being async a bit better
71 if (!d->initialize()) {
72 if (!d->isReady())
73 m_errorString = QStringLiteral("Waiting for the renderer to start.");
74 else
75 m_errorString = QStringLiteral("Failed to initialize the XR manager.");
76
77 return false;
78 }
79
80 // Setup Graphics
81 return setupGraphics();
82}
83
85{
86 Q_D(QQuick3DXrManager);
87 d->teardown();
88}
89
91{
92 Q_D(const QQuick3DXrManager);
93 return d->isValid();
94}
95
97{
98 Q_D(QQuick3DXrManager);
99 // Returns true if passthrough is supported
100 return d->setPassthroughEnabled(enabled);
101}
102
104{
105 Q_D(const QQuick3DXrManager);
106 return d->isPassthroughEnabled();
107}
108
110{
111 Q_D(QQuick3DXrManager);
112 d->setMultiViewRenderingEnabled(enable);
113}
114
116{
117 Q_D(const QQuick3DXrManager);
118 return d->isMultiViewRenderingEnabled();
119}
120
122{
123 QRhi *rhi = m_renderControl->rhi();
124 return rhi ? rhi->isFeatureSupported(QRhi::MultiView) : false;
125}
126
127void QQuick3DXrManager::setXROrigin(QQuick3DXrOrigin *origin)
128{
129 m_xrOrigin = origin;
130 update();
131}
132
133void QQuick3DXrManager::getDefaultClipDistances(float &nearClip, float &farClip) const
134{
135 Q_D(const QQuick3DXrManager);
136 d->getDefaultClipDistances(nearClip, farClip);
137}
138
140{
141#if defined(Q_OS_VISIONOS)
142 // Foveation is not configurable on VisionOS
143 return QtQuick3DXr::FoveationLevel::HighFoveation;
144#else
145 Q_D(const QQuick3DXrManager);
146 return QtQuick3DXr::FoveationLevel(d->m_foveationLevel);
147#endif
148}
149
150void QQuick3DXrManager::setFixedFoveationLevel(QtQuick3DXr::FoveationLevel level)
151{
152#if defined(Q_OS_VISIONOS)
153 // Foveation is not configurable on VisionOS
154 Q_UNUSED(level);
155#else
156 Q_D(QQuick3DXrManager);
157 const XrFoveationLevelFB xrLevel = XrFoveationLevelFB(level);
158 if (d->m_foveationLevel == xrLevel)
159 return;
160
161 d->m_foveationLevel = xrLevel;
162 d->setupMetaQuestFoveation();
163#endif
164}
165
167{
168 Q_D(const QQuick3DXrManager);
169 return d->getReferenceSpace();
170}
171
172void QQuick3DXrManager::setReferenceSpace(QtQuick3DXr::ReferenceSpace newReferenceSpace)
173{
174 Q_D(QQuick3DXrManager);
175
176 d->setReferenceSpace(newReferenceSpace);
177}
178
180{
181 Q_D(const QQuick3DXrManager);
182 return d->isDepthSubmissionEnabled();
183}
184
186{
187 Q_D(QQuick3DXrManager);
188 d->setDepthSubmissionEnabled(enable);
189}
190
192{
193 Q_D(const QQuick3DXrManager);
194 return d->errorString();
195}
196
198{
199 Q_D(QQuick3DXrManager);
200 d->setSamples(samples);
201}
202
203void QQuick3DXrManager::update()
204{
205 Q_D(QQuick3DXrManager);
206 d->update();
207}
208
209bool QQuick3DXrManager::event(QEvent *e)
210{
211 Q_D(QQuick3DXrManager);
212
213 if (e->type() == QEvent::UpdateRequest) {
214 d->processXrEvents();
215 d->update();
216 return true;
217 }
218 return QObject::event(e);
219}
220
222{
223 static bool disabled = qEnvironmentVariableIntValue("QT_QUICK3D_XR_DISABLE_MULTIVIEW") != 0;
224 return disabled;
225}
226
227QQuick3DXrInputManager *QQuick3DXrManager::getInputManager() const
228{
229 Q_D(const QQuick3DXrManager);
230 return d->m_inputManager.data();
231}
232
233bool QQuick3DXrManager::setupGraphics()
234{
235 Q_D(QQuick3DXrManager);
236
237 // FIXME: Should probably make sure we don't accidentally get here more then once
238 // or if we're re-initializing, in which case: make sure to clean up properly first.
239 if (d->isGraphicsInitialized())
240 return true;
241
242 preSetupQuickScene();
243
244 if (!d->setupGraphics(m_quickWindow))
245 return false;
246
247 if (!setupQuickScene())
248 return false;
249
250 QRhi *rhi = m_quickWindow->rhi();
251 QSSG_ASSERT_X(rhi != nullptr, "No RHI handle!", return false);
252
253 if (!d->isMultiViewRenderingEnabled())
254 emit multiViewRenderingEnabledChanged();
255
256 return d->finalizeGraphics(rhi);
257}
258
259void QQuick3DXrManager::renderFrame()
260{
261 Q_D(QQuick3DXrManager);
262
263 if (!m_xrOrigin) {
264 if (!m_xrOriginWarningShown) {
265 qWarning() << "No XrOrigin found!";
266 m_xrOriginWarningShown = true;
267 }
268 return;
269 }
270
271 d->doRenderFrame();
272}
273
274void QQuick3DXrManager::preSetupQuickScene()
275{
276 if (!m_renderControl)
277 m_renderControl = new QQuickRenderControl;
278 if (!m_quickWindow)
279 m_quickWindow = new QQuickWindow(m_renderControl);
280}
281
282bool QQuick3DXrManager::setupQuickScene()
283{
284 Q_D(QQuick3DXrManager);
285
286 d->setupWindow(m_quickWindow);
287
288 if (!m_animationDriver) {
289 m_animationDriver = new QQuick3DXrAnimationDriver;
290 m_animationDriver->install();
291 }
292
293 const bool initSuccess = m_renderControl->initialize();
294 if (!initSuccess) {
295 qWarning("Quick 3D XR: Failed to create renderControl (failed to initialize RHI?)");
296 return false;
297 }
298
299 QRhi *rhi = m_renderControl->rhi();
300 if (!rhi) {
301 qWarning("Quick3D XR: No QRhi from renderControl. This should not happen.");
302 return false;
303 }
304
305 qCDebug(lcQuick3DXr, "Quick 3D XR: QRhi initialized with backend %s", rhi->backendName());
306
307 return true;
308}
309
310bool QQuick3DXrManager::supportsPassthrough() const
311{
312 Q_D(const QQuick3DXrManager);
313 return d->supportsPassthrough();
314}
315
316QT_END_NAMESPACE
void setDepthSubmissionEnabled(bool enable)
bool isPassthroughEnabled() const
void setFixedFoveationLevel(QtQuick3DXr::FoveationLevel level)
bool isMultiViewRenderingSupported() const
QString errorString() const
QtQuick3DXr::FoveationLevel getFixedFoveationLevel() const
bool isDepthSubmissionEnabled() const
void setMultiViewRenderingEnabled(bool enable)
void setSamples(int samples)
void setXROrigin(QQuick3DXrOrigin *origin)
bool isMultiViewRenderingEnabled() const
void getDefaultClipDistances(float &nearClip, float &farClip) const
void setReferenceSpace(QtQuick3DXr::ReferenceSpace newReferenceSpace)
bool setPassthroughEnabled(bool enabled)
bool event(QEvent *e) override
This virtual function receives events to an object and should return true if the event e was recogniz...
QtQuick3DXr::ReferenceSpace getReferenceSpace() const
static bool isMultiviewRenderingDisabled()
Combined button and popup list for selecting options.
Q_LOGGING_CATEGORY(lcEventDispatcher, "qt.eventdispatcher")