1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qquick3dxrorigin_p.h"
5
6#include "qquick3dxrview_p.h"
7
8#include <QtQuick3D/private/qquick3dnode_p_p.h>
9
10#include <QtQuick3DUtils/private/qssgassert_p.h>
11
12QT_BEGIN_NAMESPACE
13
14/*!
15 \qmltype XrOrigin
16 \inherits Node
17 \inqmlmodule QtQuick3D.Xr
18 \brief The origin location for the XrView.
19
20 The origin determines the center of the \l{XrView::referenceSpace}{reference space}.
21 Changing the position of the origin will transport the user to a different position
22 in the scene.
23
24 Most XR platforms allow the user to move physically, changing the viewpoint. This
25 does not change the position of the origin. To track the position of the headset, create
26 an XrCamera and assign it to the \l camera property.
27
28 \warning Ensure you follow best practices when changing the position/rotation of
29 the origin. Not doing so may cause physical discomfort, nausea, or loss of balance.
30 In the worst case, this could lead to injury or even death.
31*/
32
33QQuick3DXrOrigin::QQuick3DXrOrigin(QQuick3DNode *parent)
34 : QQuick3DNode(parent)
35{
36 // These are the "real" cameras that are used for rendering.
37 QQuick3DXrEyeCamera *leftEyeCamera = new QQuick3DXrEyeCamera(this);
38 leftEyeCamera->setParentItem(this);
39
40 QQuick3DXrEyeCamera *rightEyeCamera = new QQuick3DXrEyeCamera(this);
41 rightEyeCamera->setParentItem(this);
42
43 m_eyeCameras = { leftEyeCamera, rightEyeCamera };
44}
45
46QQuick3DXrOrigin::~QQuick3DXrOrigin()
47{
48
49}
50
51/*!
52 \qmlproperty XrCamera QtQuick3D.Xr::XrOrigin::camera
53 \brief Property for adding a tracked camera node.
54
55 \default null
56
57 Holds an XrCamera, which is a tracked spatial node that tracks the position and orientation
58 of the head-mounted display in the XR environment.
59
60 \note This property is optional.
61
62 \sa XrCamera
63*/
64
65QQuick3DXrCamera *QQuick3DXrOrigin::camera() const
66{
67 return m_camera;
68}
69
70void QQuick3DXrOrigin::setCamera(QQuick3DXrCamera *newCamera)
71{
72 if (m_camera == newCamera)
73 return;
74
75 QQuick3DObjectPrivate::attachWatcher(context: this, setter: &QQuick3DXrOrigin::setCamera, newO: m_camera, oldO: newCamera);
76
77 m_camera = newCamera;
78
79 if (m_camera) {
80 // Ensure that the parent item is the XrOrigin
81 QQuick3DObject *camParentItem = m_camera->parentItem();
82 if (camParentItem != this) {
83 m_camera->setParentItem(this);
84 if (camParentItem != nullptr)
85 qWarning() << "XrCamera needs to be a child of XrOrigin. Reparenting...";
86 }
87
88 // If there's a camera, it will call this function to update the camera settings
89 // when its properties change.
90 syncCameraSettings();
91 } else {
92 // Restore default values
93 resetCameraSettings();
94 }
95
96 emit cameraChanged();
97}
98
99QQuick3DXrEyeCamera *QQuick3DXrOrigin::eyeCamera(int index) const
100{
101 return m_eyeCameras[index];
102}
103
104void QQuick3DXrOrigin::syncCameraSettings()
105{
106 QSSG_ASSERT(m_camera != nullptr, return);
107
108 for (auto eyeCamera : m_eyeCameras) {
109 eyeCamera->setClipNear(m_camera->clipNear());
110 eyeCamera->setClipFar(m_camera->clipFar());
111 }
112}
113
114void QQuick3DXrOrigin::resetCameraSettings()
115{
116 Q_ASSERT(!m_camera);
117
118 if (QQuick3DXrView *xrView = qobject_cast<QQuick3DXrView *>(object: parentItem())) {
119 // Use the default clip distances from the XrManager
120 float nearClip, farClip;
121 xrView->xrManager()->getDefaultClipDistances(nearClip, farClip);
122 for (auto eyeCamera : m_eyeCameras) {
123 eyeCamera->setClipNear(nearClip);
124 eyeCamera->setClipFar(farClip);
125 }
126 }
127}
128
129void QQuick3DXrOrigin::updateTrackedCamera(const QMatrix4x4 &transform)
130{
131 if (m_camera)
132 QQuick3DNodePrivate::get(node: m_camera)->setLocalTransform(transform);
133}
134
135void QQuick3DXrOrigin::updateTrackedCamera(QVector3D position, QQuaternion rotation)
136{
137 if (m_camera) {
138 m_camera->setPosition(position);
139 m_camera->setRotation(rotation);
140 }
141}
142
143QT_END_NAMESPACE
144

source code of qtquick3d/src/xr/quick3dxr/qquick3dxrorigin.cpp