Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qquick3dxrcamera.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
6
#
include
"qquick3dxrcamera_p.h"
7
#
include
"qquick3dxrorigin_p.h"
8
#
include
<
QtQuick3DRuntimeRender
/
private
/
qssgrendercamera_p
.
h
>
9
#
include
<
QtQuick3D
/
private
/
qquick3dutils_p
.
h
>
10
#
include
<
QtQuick3D
/
private
/
qquick3dnode_p_p
.
h
>
11
12
#
include
<
cmath
>
13
14
QT_BEGIN_NAMESPACE
15
/*!
16
\qmltype XrCamera
17
\inherits Node
18
\inqmlmodule QtQuick3D.Xr
19
\brief Tracks spatial position and orientation from which the user views an XR scene.
20
21
The XrCamera is a tracked spatial node that tracks the spatial position and orientation
22
of the users's view of an XR scene.
23
24
Since this is a tracked node, its spatial properties should be considered read-only.
25
Properties specific to the XrCamera, such as the \l{clipNear}{near} and \l{clipFar}{far} clip planes, are settable.
26
When set, they override preferred values.
27
28
Unlike a \l PerspectiveCamera, an XrCamera has no field of view: the runtime supplies
29
the projection for each eye.
30
31
\sa XrOrigin::camera, {Coordinate Systems and Units in \qxr}
32
*/
33
34
QQuick3DXrEyeCamera::QQuick3DXrEyeCamera(QQuick3DXrOrigin *parent)
35
: QQuick3DCamera(*(
new
QQuick3DNodePrivate(QQuick3DNodePrivate::Type::CustomCamera, QQuick3DContentLayer::LayerAll)), parent)
36
{
37
}
38
39
float
QQuick3DXrEyeCamera::leftTangent()
const
40
{
41
return
m_leftTangent;
42
}
43
44
float
QQuick3DXrEyeCamera::rightTangent()
const
45
{
46
return
m_rightTangent;
47
}
48
49
float
QQuick3DXrEyeCamera::upTangent()
const
50
{
51
return
m_upTangent;
52
}
53
54
float
QQuick3DXrEyeCamera::downTangent()
const
55
{
56
return
m_downTangent;
57
}
58
59
float
QQuick3DXrEyeCamera::clipNear()
const
60
{
61
return
m_clipNear;
62
}
63
64
float
QQuick3DXrEyeCamera::clipFar()
const
65
{
66
return
m_clipFar;
67
}
68
69
void
QQuick3DXrEyeCamera::setLeftTangent(
float
leftTangent)
70
{
71
if
(qFuzzyCompare(m_leftTangent, leftTangent))
72
return
;
73
74
m_leftTangent = leftTangent;
75
emit leftTangentChanged(m_leftTangent);
76
markDirty(DirtyFlag::ProjectionDirty);
77
}
78
79
void
QQuick3DXrEyeCamera::setRightTangent(
float
rightTangent)
80
{
81
if
(qFuzzyCompare(m_rightTangent, rightTangent))
82
return
;
83
84
m_rightTangent = rightTangent;
85
emit rightTangentChanged(m_rightTangent);
86
markDirty(DirtyFlag::ProjectionDirty);
87
}
88
89
void
QQuick3DXrEyeCamera::setUpTangent(
float
upTangent)
90
{
91
if
(qFuzzyCompare(m_upTangent, upTangent))
92
return
;
93
94
m_upTangent = upTangent;
95
emit upTangentChanged(m_upTangent);
96
markDirty(DirtyFlag::ProjectionDirty);
97
}
98
99
void
QQuick3DXrEyeCamera::setDownTangent(
float
downTangent)
100
{
101
if
(qFuzzyCompare(m_downTangent, downTangent))
102
return
;
103
104
m_downTangent = downTangent;
105
emit downTangentChanged(m_downTangent);
106
markDirty(DirtyFlag::ProjectionDirty);
107
}
108
109
void
QQuick3DXrEyeCamera::setClipNear(
float
clipNear)
110
{
111
if
(qFuzzyCompare(m_clipNear, clipNear))
112
return
;
113
114
m_clipNear = clipNear;
115
emit clipNearChanged(m_clipNear);
116
markDirty(DirtyFlag::ProjectionDirty);
117
}
118
119
void
QQuick3DXrEyeCamera::setClipFar(
float
clipFar)
120
{
121
if
(qFuzzyCompare(m_clipFar, clipFar))
122
return
;
123
124
m_clipFar = clipFar;
125
emit clipFarChanged(m_clipFar);
126
markDirty(DirtyFlag::ProjectionDirty);
127
}
128
129
void
QQuick3DXrEyeCamera::setProjection(
const
QMatrix4x4 &projection)
130
{
131
m_projection = projection;
132
markDirty(DirtyFlag::ProjectionChanged);
133
}
134
135
QSSGRenderGraphObject *QQuick3DXrEyeCamera::updateSpatialNode(QSSGRenderGraphObject *node)
136
{
137
QSSGRenderCamera *camera =
static_cast
<QSSGRenderCamera *>(QQuick3DCamera::updateSpatialNode(node));
138
if
(camera) {
139
// Projection changed takes precedence over projection dirty
140
bool
changed =
false
;
141
if
(m_dirtyFlags & DirtyFlag::ProjectionChanged) {
142
camera->projection = m_projection;
143
qUpdateIfNeeded(camera->clipPlanes, { m_clipNear, m_clipFar });
144
m_dirtyFlags &= ~DirtyFlag::ProjectionChanged;
145
changed =
true
;
146
}
else
if
(m_dirtyFlags & DirtyFlag::ProjectionDirty) {
147
maybeUpdateProjection();
148
changed |= qUpdateIfNeeded(camera->projection, m_projection);
149
qUpdateIfNeeded(camera->clipPlanes, { m_clipNear, m_clipFar });
150
m_dirtyFlags &= ~DirtyFlag::ProjectionDirty;
151
}
152
153
if
(m_dirtyFlags & DirtyFlag::ClipChanged) {
154
qUpdateIfNeeded(camera->clipPlanes, { m_clipNear, m_clipFar });
155
m_dirtyFlags &= ~DirtyFlag::ClipChanged;
156
}
157
158
// Reset the dirty flag after all updates have been done
159
m_dirtyFlags = 0;
160
161
if
(changed)
162
camera->markDirty(QSSGRenderCamera::DirtyFlag::CameraDirty);
163
}
164
return
camera;
165
}
166
167
void
QQuick3DXrEyeCamera::markDirty(DirtyFlag flag)
168
{
169
if
(m_dirtyFlags & flag)
170
return
;
171
172
m_dirtyFlags |= flag;
173
update();
174
}
175
176
void
QQuick3DXrEyeCamera::maybeUpdateProjection()
177
{
178
QSSG_ASSERT(m_dirtyFlags & DirtyFlag::ProjectionDirty,
return
);
179
180
const
float
right = m_rightTangent * m_clipNear;
181
const
float
top = m_upTangent * m_clipNear;
182
#
if
defined
(
Q_OS_VISIONOS
)
183
// cp_view_get_tangents always returns positive values
184
// so we need to negate the left and down tangents
185
const
float
left = -m_leftTangent * m_clipNear;
186
const
float
bottom = -m_downTangent * m_clipNear;
187
#
else
188
const
float
left = m_leftTangent * m_clipNear;
189
const
float
bottom = m_downTangent * m_clipNear;
190
#
endif
191
192
float
*m = m_projection.data();
193
194
m[0] = 2 * m_clipNear / (right - left);
195
m[4] = 0;
196
m[8] = (right + left) / (right - left);
197
m[12] = 0;
198
199
m[1] = 0;
200
m[5] = 2 * m_clipNear / (top - bottom);
201
m[9] = (top + bottom) / (top - bottom);
202
m[13] = 0;
203
204
m[2] = 0;
205
m[6] = 0;
206
m[10] = m_clipFar / (m_clipNear - m_clipFar);
207
m[14] = m_clipFar * m_clipNear / (m_clipNear - m_clipFar);
208
209
210
m[3] = 0;
211
m[7] = 0;
212
m[11] = -1;
213
m[15] = 0;
214
215
const
bool
isReverseZ =
false
;
// placeholder
216
if
(isReverseZ) {
217
if
(std::isinf(m_clipFar)) {
218
m[10] = 0;
219
m[14] = m_clipNear;
220
}
else
{
221
m[10] = -m[10] - 1;
222
m[14] = -m[14];
223
}
224
}
else
if
(std::isinf(m_clipFar)) {
225
m[10] = -1;
226
m[14] = -m_clipNear;
227
}
228
}
229
230
QQuick3DXrCamera::QQuick3DXrCamera(QQuick3DXrOrigin *parent)
231
: QQuick3DNode(parent)
232
{
233
}
234
235
QQuick3DXrCamera::~QQuick3DXrCamera()
236
{
237
}
238
239
/*!
240
\qmlproperty real QtQuick3D.Xr::XrCamera::clipNear
241
\brief The start of the distance range, with reference to the camera position, in which objects will appear.
242
243
The distance is in centimeters, like every other distance in an XR scene.
244
245
\note Unless set explicitly, the clipNear value will be set to the device's preferred value.
246
247
\sa {Coordinate Systems and Units in \qxr}
248
*/
249
250
float
QQuick3DXrCamera::clipNear()
const
251
{
252
return
m_clipNear;
253
}
254
255
/*!
256
\qmlproperty real QtQuick3D.Xr::XrCamera::clipFar
257
\brief The end of the distance range, with reference to the camera position, in which objects will appear.
258
259
The distance is in centimeters, like every other distance in an XR scene.
260
261
\note Unless set explicitly, the clipFar value will be set to the device's preferred value.
262
263
\sa {Coordinate Systems and Units in \qxr}
264
*/
265
266
float
QQuick3DXrCamera::clipFar()
const
267
{
268
return
m_clipFar;
269
}
270
271
void
QQuick3DXrCamera::setClipNear(
float
clipNear)
272
{
273
if
(qFuzzyCompare(m_clipNear, clipNear))
274
return
;
275
276
m_clipNear = clipNear;
277
278
syncCameraSettings();
279
280
emit clipNearChanged(m_clipNear);
281
}
282
283
void
QQuick3DXrCamera::setClipFar(
float
clipFar)
284
{
285
if
(qFuzzyCompare(m_clipFar, clipFar))
286
return
;
287
288
m_clipFar = clipFar;
289
290
syncCameraSettings();
291
292
emit clipFarChanged(m_clipFar);
293
}
294
295
void
QQuick3DXrCamera::itemChange(ItemChange change,
const
ItemChangeData &data)
296
{
297
// Sanity check (If we get a tracked item we'll do this there instead).
298
if
(change == QQuick3DObject::ItemParentHasChanged) {
299
if
(data.item !=
nullptr
) {
300
if
(QQuick3DXrOrigin *xrOrigin = qobject_cast<QQuick3DXrOrigin *>(data.item)) {
301
xrOrigin->setCamera(
this
);
302
}
else
{
303
qWarning() <<
"XrCamera must be a child of an XrOrigin!"
;
304
setParentItem(
nullptr
);
305
}
306
}
else
{
307
QQuick3DNode::itemChange(change, data);
308
}
309
}
310
}
311
312
void
QQuick3DXrCamera::syncCameraSettings()
313
{
314
QQuick3DXrOrigin *xrOrigin = qobject_cast<QQuick3DXrOrigin *>(parentItem());
315
if
(xrOrigin && xrOrigin->camera() ==
this
)
316
xrOrigin->syncCameraSettings();
317
}
318
319
QT_END_NAMESPACE
qtquick3d
src
xr
quick3dxr
qquick3dxrcamera.cpp
Generated on
for Qt by
1.18.0