6#include <QtQuick3DRuntimeRender/private/qssgrendercamera_p.h>
7#include <QtQuick3D/private/qquick3dutils_p.h>
8#include <QtQuick3D/private/qquick3dnode_p_p.h>
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
30QQuick3DXrEyeCamera::QQuick3DXrEyeCamera(QQuick3DXrOrigin *parent)
31 : QQuick3DCamera(*(
new QQuick3DNodePrivate(QQuick3DNodePrivate::Type::CustomCamera, QQuick3DContentLayer::LayerAll)), parent)
35float QQuick3DXrEyeCamera::leftTangent()
const
40float QQuick3DXrEyeCamera::rightTangent()
const
42 return m_rightTangent;
45float QQuick3DXrEyeCamera::upTangent()
const
50float QQuick3DXrEyeCamera::downTangent()
const
55float QQuick3DXrEyeCamera::clipNear()
const
60float QQuick3DXrEyeCamera::clipFar()
const
65void QQuick3DXrEyeCamera::setLeftTangent(
float leftTangent)
67 if (qFuzzyCompare(m_leftTangent, leftTangent))
70 m_leftTangent = leftTangent;
71 emit leftTangentChanged(m_leftTangent);
72 markDirty(DirtyFlag::ProjectionDirty);
75void QQuick3DXrEyeCamera::setRightTangent(
float rightTangent)
77 if (qFuzzyCompare(m_rightTangent, rightTangent))
80 m_rightTangent = rightTangent;
81 emit rightTangentChanged(m_rightTangent);
82 markDirty(DirtyFlag::ProjectionDirty);
85void QQuick3DXrEyeCamera::setUpTangent(
float upTangent)
87 if (qFuzzyCompare(m_upTangent, upTangent))
90 m_upTangent = upTangent;
91 emit upTangentChanged(m_upTangent);
92 markDirty(DirtyFlag::ProjectionDirty);
95void QQuick3DXrEyeCamera::setDownTangent(
float downTangent)
97 if (qFuzzyCompare(m_downTangent, downTangent))
100 m_downTangent = downTangent;
101 emit downTangentChanged(m_downTangent);
102 markDirty(DirtyFlag::ProjectionDirty);
105void QQuick3DXrEyeCamera::setClipNear(
float clipNear)
107 if (qFuzzyCompare(m_clipNear, clipNear))
110 m_clipNear = clipNear;
111 emit clipNearChanged(m_clipNear);
112 markDirty(DirtyFlag::ProjectionDirty);
115void QQuick3DXrEyeCamera::setClipFar(
float clipFar)
117 if (qFuzzyCompare(m_clipFar, clipFar))
121 emit clipFarChanged(m_clipFar);
122 markDirty(DirtyFlag::ProjectionDirty);
125void QQuick3DXrEyeCamera::setProjection(
const QMatrix4x4 &projection)
127 m_projection = projection;
128 markDirty(DirtyFlag::ProjectionChanged);
131QSSGRenderGraphObject *QQuick3DXrEyeCamera::updateSpatialNode(QSSGRenderGraphObject *node)
133 QSSGRenderCamera *camera =
static_cast<QSSGRenderCamera *>(QQuick3DCamera::updateSpatialNode(node));
136 bool changed =
false;
137 if (m_dirtyFlags & DirtyFlag::ProjectionChanged) {
138 camera->projection = m_projection;
139 qUpdateIfNeeded(camera->clipPlanes, { m_clipNear, m_clipFar });
140 m_dirtyFlags &= ~DirtyFlag::ProjectionChanged;
142 }
else if (m_dirtyFlags & DirtyFlag::ProjectionDirty) {
143 maybeUpdateProjection();
144 changed |= qUpdateIfNeeded(camera->projection, m_projection);
145 qUpdateIfNeeded(camera->clipPlanes, { m_clipNear, m_clipFar });
146 m_dirtyFlags &= ~DirtyFlag::ProjectionDirty;
149 if (m_dirtyFlags & DirtyFlag::ClipChanged) {
150 qUpdateIfNeeded(camera->clipPlanes, { m_clipNear, m_clipFar });
151 m_dirtyFlags &= ~DirtyFlag::ClipChanged;
158 camera->markDirty(QSSGRenderCamera::DirtyFlag::CameraDirty);
163void QQuick3DXrEyeCamera::markDirty(DirtyFlag flag)
165 if (m_dirtyFlags & flag)
168 m_dirtyFlags |= flag;
172void QQuick3DXrEyeCamera::maybeUpdateProjection()
174 QSSG_ASSERT(m_dirtyFlags & DirtyFlag::ProjectionDirty,
return);
176 const float right = m_rightTangent * m_clipNear;
177 const float top = m_upTangent * m_clipNear;
178#if defined(Q_OS_VISIONOS)
181 const float left = -m_leftTangent * m_clipNear;
182 const float bottom = -m_downTangent * m_clipNear;
184 const float left = m_leftTangent * m_clipNear;
185 const float bottom = m_downTangent * m_clipNear;
188 float *m = m_projection.data();
190 m[0] = 2 * m_clipNear / (right - left);
192 m[8] = (right + left) / (right - left);
196 m[5] = 2 * m_clipNear / (top - bottom);
197 m[9] = (top + bottom) / (top - bottom);
202 m[10] = m_clipFar / (m_clipNear - m_clipFar);
203 m[14] = m_clipFar * m_clipNear / (m_clipNear - m_clipFar);
211 const bool isReverseZ =
false;
213 if (std::isinf(m_clipFar)) {
220 }
else if (std::isinf(m_clipFar)) {
226QQuick3DXrCamera::QQuick3DXrCamera(QQuick3DXrOrigin *parent)
227 : QQuick3DNode(parent)
231QQuick3DXrCamera::~QQuick3DXrCamera()
236
237
238
239
240
242float QQuick3DXrCamera::clipNear()
const
248
249
250
251
252
254float QQuick3DXrCamera::clipFar()
const
259void QQuick3DXrCamera::setClipNear(
float clipNear)
261 if (qFuzzyCompare(m_clipNear, clipNear))
264 m_clipNear = clipNear;
266 syncCameraSettings();
268 emit clipNearChanged(m_clipNear);
271void QQuick3DXrCamera::setClipFar(
float clipFar)
273 if (qFuzzyCompare(m_clipFar, clipFar))
278 syncCameraSettings();
280 emit clipFarChanged(m_clipFar);
283void QQuick3DXrCamera::itemChange(ItemChange change,
const ItemChangeData &data)
286 if (change == QQuick3DObject::ItemParentHasChanged) {
287 if (data.item !=
nullptr) {
288 if (QQuick3DXrOrigin *xrOrigin = qobject_cast<QQuick3DXrOrigin *>(data.item)) {
289 xrOrigin->setCamera(
this);
291 qWarning() <<
"XrCamera must be a child of an XrOrigin!";
292 setParentItem(
nullptr);
295 QQuick3DNode::itemChange(change, data);
300void QQuick3DXrCamera::syncCameraSettings()
302 QQuick3DXrOrigin *xrOrigin = qobject_cast<QQuick3DXrOrigin *>(parentItem());
303 if (xrOrigin && xrOrigin->camera() ==
this)
304 xrOrigin->syncCameraSettings();