8#include <QtQuick3DRuntimeRender/private/qssgrendercamera_p.h>
9#include <QtQuick3D/private/qquick3dutils_p.h>
10#include <QtQuick3D/private/qquick3dnode_p_p.h>
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
32QQuick3DXrEyeCamera::QQuick3DXrEyeCamera(QQuick3DXrOrigin *parent)
33 : QQuick3DCamera(*(
new QQuick3DNodePrivate(QQuick3DNodePrivate::Type::CustomCamera, QQuick3DContentLayer::LayerAll)), parent)
37float QQuick3DXrEyeCamera::leftTangent()
const
42float QQuick3DXrEyeCamera::rightTangent()
const
44 return m_rightTangent;
47float QQuick3DXrEyeCamera::upTangent()
const
52float QQuick3DXrEyeCamera::downTangent()
const
57float QQuick3DXrEyeCamera::clipNear()
const
62float QQuick3DXrEyeCamera::clipFar()
const
67void QQuick3DXrEyeCamera::setLeftTangent(
float leftTangent)
69 if (qFuzzyCompare(m_leftTangent, leftTangent))
72 m_leftTangent = leftTangent;
73 emit leftTangentChanged(m_leftTangent);
74 markDirty(DirtyFlag::ProjectionDirty);
77void QQuick3DXrEyeCamera::setRightTangent(
float rightTangent)
79 if (qFuzzyCompare(m_rightTangent, rightTangent))
82 m_rightTangent = rightTangent;
83 emit rightTangentChanged(m_rightTangent);
84 markDirty(DirtyFlag::ProjectionDirty);
87void QQuick3DXrEyeCamera::setUpTangent(
float upTangent)
89 if (qFuzzyCompare(m_upTangent, upTangent))
92 m_upTangent = upTangent;
93 emit upTangentChanged(m_upTangent);
94 markDirty(DirtyFlag::ProjectionDirty);
97void QQuick3DXrEyeCamera::setDownTangent(
float downTangent)
99 if (qFuzzyCompare(m_downTangent, downTangent))
102 m_downTangent = downTangent;
103 emit downTangentChanged(m_downTangent);
104 markDirty(DirtyFlag::ProjectionDirty);
107void QQuick3DXrEyeCamera::setClipNear(
float clipNear)
109 if (qFuzzyCompare(m_clipNear, clipNear))
112 m_clipNear = clipNear;
113 emit clipNearChanged(m_clipNear);
114 markDirty(DirtyFlag::ProjectionDirty);
117void QQuick3DXrEyeCamera::setClipFar(
float clipFar)
119 if (qFuzzyCompare(m_clipFar, clipFar))
123 emit clipFarChanged(m_clipFar);
124 markDirty(DirtyFlag::ProjectionDirty);
127void QQuick3DXrEyeCamera::setProjection(
const QMatrix4x4 &projection)
129 m_projection = projection;
130 markDirty(DirtyFlag::ProjectionChanged);
133QSSGRenderGraphObject *QQuick3DXrEyeCamera::updateSpatialNode(QSSGRenderGraphObject *node)
135 QSSGRenderCamera *camera =
static_cast<QSSGRenderCamera *>(QQuick3DCamera::updateSpatialNode(node));
138 bool changed =
false;
139 if (m_dirtyFlags & DirtyFlag::ProjectionChanged) {
140 camera->projection = m_projection;
141 qUpdateIfNeeded(camera->clipPlanes, { m_clipNear, m_clipFar });
142 m_dirtyFlags &= ~DirtyFlag::ProjectionChanged;
144 }
else if (m_dirtyFlags & DirtyFlag::ProjectionDirty) {
145 maybeUpdateProjection();
146 changed |= qUpdateIfNeeded(camera->projection, m_projection);
147 qUpdateIfNeeded(camera->clipPlanes, { m_clipNear, m_clipFar });
148 m_dirtyFlags &= ~DirtyFlag::ProjectionDirty;
151 if (m_dirtyFlags & DirtyFlag::ClipChanged) {
152 qUpdateIfNeeded(camera->clipPlanes, { m_clipNear, m_clipFar });
153 m_dirtyFlags &= ~DirtyFlag::ClipChanged;
160 camera->markDirty(QSSGRenderCamera::DirtyFlag::CameraDirty);
165void QQuick3DXrEyeCamera::markDirty(DirtyFlag flag)
167 if (m_dirtyFlags & flag)
170 m_dirtyFlags |= flag;
174void QQuick3DXrEyeCamera::maybeUpdateProjection()
176 QSSG_ASSERT(m_dirtyFlags & DirtyFlag::ProjectionDirty,
return);
178 const float right = m_rightTangent * m_clipNear;
179 const float top = m_upTangent * m_clipNear;
180#if defined(Q_OS_VISIONOS)
183 const float left = -m_leftTangent * m_clipNear;
184 const float bottom = -m_downTangent * m_clipNear;
186 const float left = m_leftTangent * m_clipNear;
187 const float bottom = m_downTangent * m_clipNear;
190 float *m = m_projection.data();
192 m[0] = 2 * m_clipNear / (right - left);
194 m[8] = (right + left) / (right - left);
198 m[5] = 2 * m_clipNear / (top - bottom);
199 m[9] = (top + bottom) / (top - bottom);
204 m[10] = m_clipFar / (m_clipNear - m_clipFar);
205 m[14] = m_clipFar * m_clipNear / (m_clipNear - m_clipFar);
213 const bool isReverseZ =
false;
215 if (std::isinf(m_clipFar)) {
222 }
else if (std::isinf(m_clipFar)) {
228QQuick3DXrCamera::QQuick3DXrCamera(QQuick3DXrOrigin *parent)
229 : QQuick3DNode(parent)
233QQuick3DXrCamera::~QQuick3DXrCamera()
238
239
240
241
242
244float QQuick3DXrCamera::clipNear()
const
250
251
252
253
254
256float QQuick3DXrCamera::clipFar()
const
261void QQuick3DXrCamera::setClipNear(
float clipNear)
263 if (qFuzzyCompare(m_clipNear, clipNear))
266 m_clipNear = clipNear;
268 syncCameraSettings();
270 emit clipNearChanged(m_clipNear);
273void QQuick3DXrCamera::setClipFar(
float clipFar)
275 if (qFuzzyCompare(m_clipFar, clipFar))
280 syncCameraSettings();
282 emit clipFarChanged(m_clipFar);
285void QQuick3DXrCamera::itemChange(ItemChange change,
const ItemChangeData &data)
288 if (change == QQuick3DObject::ItemParentHasChanged) {
289 if (data.item !=
nullptr) {
290 if (QQuick3DXrOrigin *xrOrigin = qobject_cast<QQuick3DXrOrigin *>(data.item)) {
291 xrOrigin->setCamera(
this);
293 qWarning() <<
"XrCamera must be a child of an XrOrigin!";
294 setParentItem(
nullptr);
297 QQuick3DNode::itemChange(change, data);
302void QQuick3DXrCamera::syncCameraSettings()
304 QQuick3DXrOrigin *xrOrigin = qobject_cast<QQuick3DXrOrigin *>(parentItem());
305 if (xrOrigin && xrOrigin->camera() ==
this)
306 xrOrigin->syncCameraSettings();