12#include <QtQuick3D/private/qquick3dviewport_p.h>
13#include <QtQuick3D/private/qquick3dnode_p_p.h>
15#include <QtQuick3DUtils/private/qssgassert_p.h>
17#include <QQuickGraphicsDevice>
20#include <CompositorServices/CompositorServices.h>
21#include <QtGui/qguiapplication_platform.h>
23#include <QtCore/qoperatingsystemversion.h>
31 void configure(cp_layer_renderer_capabilities_t capabilities, cp_layer_renderer_configuration_t configuration)
const override
34 const bool supportsFoveation =
false && cp_layer_renderer_capabilities_supports_foveation(capabilities);
36 cp_layer_renderer_configuration_set_layout(configuration, cp_layer_renderer_layout_dedicated);
37 cp_layer_renderer_configuration_set_foveation_enabled(configuration, supportsFoveation);
38 cp_layer_renderer_configuration_set_color_format(configuration, MTLPixelFormatRGBA16Float);
61 return m_layerRenderer;
70 cp_layer_renderer_t m_layerRenderer =
nullptr;
71 bool m_active =
false;
83 ar_session_stop(m_arSession);
92bool QQuick3DXrManagerPrivate::initialize()
96 if (!m_worldTrackingProvider)
100 if (!s_compositorLayer->isActive()) {
101 if (
auto *visionOSApplicaton =
qGuiApp->nativeInterface<QNativeInterface::QVisionOSApplication>()) {
102 visionOSApplicaton->setImmersiveSpaceCompositorLayer(&(*s_compositorLayer));
103 s_compositorLayer->setActive();
111 return s_compositorLayer->layerRenderer() ==
nullptr ?
false :
true;
116 qWarning(
"QQuick3DXrManagerPrivate: Layer renderer is not available.");
126 qWarning(
"QQuick3DXrManagerPrivate: Window is null!");
132 qWarning(
"QQuick3DXrManagerPrivate: Layer renderer is not available.");
137 auto commandQueue = [
device newCommandQueue];
139 auto qqGraphicsDevice = QQuickGraphicsDevice::fromDeviceAndCommandQueue(
static_cast<MTLDevice*
>(
device),
static_cast<MTLCommandQueue *
>(commandQueue));
141 window->setGraphicsDevice(qqGraphicsDevice);
147 m_isGraphicsInitialized =
true;
148 return m_isGraphicsInitialized;
153 return (s_compositorLayer->layerRenderer() !=
nullptr);
158 return m_isGraphicsInitialized;
169void QQuick3DXrManagerPrivate::createSwapchains()
187 switch (cp_layer_renderer_get_state(
renderer)) {
188 case cp_layer_renderer_state_paused:
190 case cp_layer_renderer_state_running:
192 case cp_layer_renderer_state_invalidated:
198void QQuick3DXrManagerPrivate::teardown()
232 qWarning(
"Depth submission is required on VisionOS");
237 return s_compositorLayer->layerRenderer();
242 ar_device_anchor_t outAnchor = ar_device_anchor_create();
243 cp_time_t presentationTime = cp_frame_timing_get_presentation_time(timing);
244 CFTimeInterval queryTime = cp_time_to_cf_time_interval(presentationTime);
245 ar_device_anchor_query_status_t status = ar_world_tracking_provider_query_device_anchor_at_timestamp(m_worldTrackingProvider, queryTime, outAnchor);
246 if (status != ar_device_anchor_query_status_success) {
247 NSLog(
@"Failed to get estimated pose from world tracking provider for presentation timestamp %0.3f", queryTime);
261 static bool logOnce[3] = {
false,
false,
false};
274 qDebug() <<
"-- Running --";
281 qDebug() <<
"-- Invalidated --";
286 emit q->sessionEnded();
292 ar_world_tracking_configuration_t worldTrackingConfiguration = ar_world_tracking_configuration_create();
293 m_worldTrackingProvider = ar_world_tracking_provider_create(worldTrackingConfiguration);
296 ar_data_providers_add_data_provider(dataProviders, m_worldTrackingProvider);
301 if (!m_anchorManager)
306 if (
QSSG_GUARD_X(m_inputManager !=
nullptr,
"No InputManager available!")) {
309 pim->prepareHandtracking(dataProviders);
312 if (
QSSG_GUARD_X(m_anchorManager !=
nullptr,
"No AnchorManager available!"))
313 m_anchorManager->prepareAnchorManager(dataProviders);
315 m_arSession = ar_session_create();
316 ar_session_run(m_arSession, dataProviders);
320 pim->initHandtracking();
322 if (m_anchorManager !=
nullptr)
323 m_anchorManager->initAnchorManager();
329 qWarning(
"Setting samples is not supported");
340 return versionNumber;
357 QSSG_ASSERT_X(quickWindow && renderControl && xrViewport,
"Invalid state, rendering aborted",
return);
360 qWarning(
"No XR origin, trying to recover...");
366 if (
frame ==
nullptr) {
367 qWarning(
"Failed to get next frame");
371 cp_frame_timing_t timing = cp_frame_predict_timing(
frame);
372 if (timing ==
nullptr) {
373 qWarning(
"Failed to get timing for frame");
377 cp_frame_start_update(
frame);
379 cp_frame_end_update(
frame);
381 cp_time_wait_until(cp_frame_timing_get_optimal_input_time(timing));
383 cp_frame_start_submission(
frame);
384 cp_drawable_t drawable = cp_frame_query_drawable(
frame);
385 if (drawable ==
nullptr) {
386 qWarning(
"Failed to get drawable for frame");
390 cp_frame_timing_t actualTiming = cp_drawable_get_frame_timing(drawable);
392 cp_drawable_set_device_anchor(drawable, anchor);
395 simd_float4x4 headTransform = ar_anchor_get_origin_from_anchor_transform(anchor);
401 QRhi *rhi = renderControl->
rhi();
403 for (
size_t i = 0,
end = cp_drawable_get_view_count(drawable);
i !=
end ; ++
i) {
405 id<MTLTexture> colorMetalTexture = cp_drawable_get_color_texture(drawable,
i);
406 auto textureSize =
QSize([colorMetalTexture
width], [colorMetalTexture
height]);
407 auto renderTarget = QQuickRenderTarget::fromMetalTexture(
static_cast<MTLTexture*
>(colorMetalTexture), [colorMetalTexture pixelFormat], textureSize);
409 auto depthMetalTexture = cp_drawable_get_depth_texture(drawable,
i);
410 auto depthTextureSize =
QSize([depthMetalTexture
width], [depthMetalTexture
height]);
411 MTLPixelFormat depthTextureFormat = [depthMetalTexture pixelFormat];
414 case MTLPixelFormatDepth16Unorm:
416 case MTLPixelFormatDepth32Float:
419 qWarning(
"Unsupported depth texture format");
423 auto depthFormat = convertFormat(depthTextureFormat);
425 if (m_rhiDepthTexture && (m_rhiDepthTexture->
format() != depthFormat || m_rhiDepthTexture->
pixelSize() != depthTextureSize)) {
426 delete m_rhiDepthTexture;
427 m_rhiDepthTexture =
nullptr;
430 if (!m_rhiDepthTexture)
434 m_rhiDepthTexture->
createFrom({
quint64(
static_cast<MTLTexture*
>(depthMetalTexture)), 0});
435 renderTarget.setDepthTexture(m_rhiDepthTexture);
438 quickWindow->setRenderTarget(renderTarget);
444 textureSize.height());
446 textureSize.height()));
450 cp_view_t
view = cp_drawable_get_view(drawable,
i);
451 simd_float4 tangents = cp_view_get_tangents(
view);
452 const float tangentLeft = tangents[0];
453 const float tangentRight = tangents[1];
454 const float tangentUp = tangents[2];
455 const float tangentDown = tangents[3];
457 simd_float2 depth_range = cp_drawable_get_depth_range(drawable);
458 const float clipNear = depth_range[1];
459 const float clipFar = depth_range[0];
468 simd_float4x4 localEyeTransform = cp_view_get_transform(
view);
469 simd_float4x4 eyeCameraTransform = simd_mul(headTransform, localEyeTransform);
471 QMatrix4x4 transform{eyeCameraTransform.columns[0].x, eyeCameraTransform.columns[1].x, eyeCameraTransform.columns[2].x, eyeCameraTransform.columns[3].x * 100,
472 eyeCameraTransform.columns[0].y, eyeCameraTransform.columns[1].y, eyeCameraTransform.columns[2].y, eyeCameraTransform.columns[3].y * 100,
473 eyeCameraTransform.columns[0].z, eyeCameraTransform.columns[1].z, eyeCameraTransform.columns[2].z, eyeCameraTransform.columns[3].z * 100,
474 0.0f, 0.0f, 0.0f, 1.0f};
476 xrViewport->setCamera(xrOrigin->eyeCamera(
i));
481 renderControl->
sync();
488 cp_drawable_encode_present(drawable, commandBuffer);
491 cp_frame_end_submission(
frame);
496#include "qquick3dxrmanager_visionos.moc"
IOBluetoothDevice * device
void configure(cp_layer_renderer_capabilities_t capabilities, cp_layer_renderer_configuration_t configuration) const override
void renderingRequested()
void layerRendererChanged()
cp_layer_renderer_t layerRenderer() const
void handleSpatialEventsRequested(const QJsonObject &jsonString)
void render(cp_layer_renderer_t renderer) override
void handleSpatialEvents(const QJsonObject &events) override
\inmodule QtCore\reentrant
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
static Q_CORE_EXPORT QOperatingSystemVersionBase current()
static QQuick3DNodePrivate * get(QQuick3DNode *node)
static QQuick3DXrAnchorManager * instance()
void setDownTangent(float downTangent)
void setUpTangent(float upTangent)
void setClipNear(float clipNear)
void setRightTangent(float rightTangent)
void setClipFar(float clipFar)
void setLeftTangent(float leftTangent)
QQuick3DXrManagerPrivate(QQuick3DXrManager &manager)
void setupWindow(QQuickWindow *window)
bool finalizeGraphics(QRhi *rhi)
QVersionNumber runtimeVersion() const
QtQuick3DXr::ReferenceSpace getReferenceSpace() const
void setReferenceSpace(QtQuick3DXr::ReferenceSpace newReferenceSpace)
cp_layer_renderer_t layerRenderer() const
~QQuick3DXrManagerPrivate()
ar_device_anchor_t createPoseForTiming(cp_frame_timing_t timing)
bool setupGraphics(QQuickWindow *window)
void setDepthSubmissionEnabled(bool enable)
static QQuick3DXrManagerPrivate * get(QQuick3DXrManager *manager)
QString errorString() const
void setSamples(int samples)
bool isGraphicsInitialized() const
void setMultiviewRenderingEnabled(bool enable)
RenderState getRenderState()
QString runtimeName() const
void runWorldTrackingARSession()
void setPassthroughEnabled(bool enable)
void setSize(const QSizeF &size)
The QQuickRenderControl class provides a mechanism for rendering the Qt Quick scenegraph onto an offs...
void endFrame()
Specifies the end of a graphics frame.
void render()
Renders the scenegraph using the current context.
void beginFrame()
Specifies the start of a graphics frame.
void polishItems()
This function should be called as late as possible before sync().
bool sync()
This function is used to synchronize the QML scene with the rendering scene graph.
\qmltype Window \instantiates QQuickWindow \inqmlmodule QtQuick
QQuickItem * contentItem
\qmlattachedproperty Item Window::contentItem
Format
Specifies the texture format.
virtual bool createFrom(NativeTexture src)
Similar to create(), except that no new native textures are created.
\inmodule QtGuiPrivate \inheaderfile rhi/qrhi.h
QRhiTexture * newTexture(QRhiTexture::Format format, const QSize &pixelSize, int sampleCount=1, QRhiTexture::Flags flags={})
const QRhiNativeHandles * nativeHandles()
\macro QT_RESTRICTED_CAST_FROM_ASCII
void setGeometry(int posx, int posy, int w, int h)
Sets the geometry of the window, excluding its window frame, to a rectangle constructed from posx,...
Combined button and popup list for selecting options.
@ ReferenceSpaceLocalFloor
VkCommandBuffer commandBuffer
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
GLint GLsizei GLsizei height
GLint GLint GLint GLint GLsizei GLsizei GLsizei GLboolean commit
GLint GLsizei GLsizei GLenum format
GLuint GLenum GLenum transform
GLdouble GLdouble GLdouble GLdouble q
struct ar_data_providers_s * ar_data_providers_t
#define QSSG_ASSERT_X(cond, msg, action)
#define QSSG_GUARD_X(cond, msg)
#define QSSG_ASSERT(cond, action)
#define QStringLiteral(str)
#define Q_UNIMPLEMENTED()
unsigned long long quint64
QNetworkAccessManager manager
QSvgRenderer * renderer
[0]