1 | // Copyright (C) 2024 The Qt Company Ltd. |
---|---|
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
3 | |
4 | #include "qquick3dxrspatialanchor_p.h" |
5 | |
6 | #if defined(Q_OS_VISIONOS) |
7 | #include "visionos/qquick3dxranchormanager_visionos_p.h" |
8 | #else |
9 | #include "openxr/qquick3dxranchormanager_openxr_p.h" |
10 | #endif |
11 | |
12 | QT_BEGIN_NAMESPACE |
13 | |
14 | /*! |
15 | \qmltype XrSpatialAnchor |
16 | \inherits QtObject |
17 | \inqmlmodule QtQuick3D.Xr |
18 | \brief Tracks a specific location or object in real space. |
19 | |
20 | This type represents a spatial anchor that tracks |
21 | a specific location or object in real space. It provides information about |
22 | the anchor's position, rotation, classification, and bounds. |
23 | |
24 | Spatial anchors are accessed through an \l XrSpatialAnchorListModel. |
25 | |
26 | \note The system provides Anchor objects. They cannot be created in QML. |
27 | |
28 | See the \l{Qt Quick 3D - XR Spatial Anchors Example} for how to use this type. |
29 | |
30 | \section1 Platform notes |
31 | |
32 | \section2 Meta Quest Devices |
33 | |
34 | This API makes use of the Meta Quest Scene and Spatial Anchor APIs. |
35 | You need to add the following permissions to your app's \c AndroidManifest.xml file: |
36 | |
37 | \badcode |
38 | <uses-permission android:name="com.oculus.permission.USE_ANCHOR_API"/> |
39 | <uses-permission android:name="com.oculus.permission.USE_SCENE"/> |
40 | \endcode |
41 | |
42 | \note You need to manually set up a Space before running an app, or anchors will |
43 | not be available. |
44 | */ |
45 | |
46 | /*! |
47 | \qmlproperty enumeration XrSpatialAnchor::Classification |
48 | \ingroup xr-anchors |
49 | \brief The classification of the spatial anchor. |
50 | \readonly |
51 | |
52 | The Classification enum provides a set of predefined category types that describe |
53 | the purpose or context of a spatial anchor. |
54 | |
55 | \value Classification.Unknown The label has not been set or identified. |
56 | \value Classification.Wall The anchor represents a wall. |
57 | \value Classification.Ceiling The anchor represents a ceiling. |
58 | \value Classification.Floor The anchor represents a floor. |
59 | \value Classification.Table The anchor represents a table. |
60 | \value Classification.Seat The anchor represents a seat. |
61 | \value Classification.Window The anchor represents a window. |
62 | \value Classification.Door The anchor represents a door. |
63 | \value Classification.Other The anchor was not identified as any of the above types. See: \l classificationString |
64 | |
65 | The following table shows the mapping between the classification type in \qxr, |
66 | OpenXR, and VisionOS. If the classification type from the system falls outside of the defined types, |
67 | then the \e Type is set to \c Other, and the system type is provided by the \l classificationString property. |
68 | |
69 | \note The classification string can also be \c{Other}. |
70 | |
71 | \table |
72 | \header |
73 | \li Type |
74 | \li OpenXR |
75 | \li VisionOS |
76 | \li Description |
77 | \row |
78 | \li Unknown |
79 | \li - |
80 | \li - |
81 | \li The label has not been set or identified. |
82 | \row |
83 | \li Wall |
84 | \li WALL_FACE |
85 | \li Wall |
86 | \li The anchor represents a wall. |
87 | \row |
88 | \li Ceiling |
89 | \li CEILING |
90 | \li Ceiling |
91 | \li The anchor represents a ceiling. |
92 | \row |
93 | \li Floor |
94 | \li FLOOR |
95 | \li Floor |
96 | \li The anchor represents a floor. |
97 | \row |
98 | \li Table |
99 | \li TABLE |
100 | \li Table |
101 | \li The anchor represents a table. |
102 | \row |
103 | \li Seat |
104 | \li COUCH |
105 | \li Seat |
106 | \li The anchor represents a seat. |
107 | \row |
108 | \li Window |
109 | \li WINDOW_FRAME |
110 | \li Window |
111 | \li The anchor represents a window. |
112 | \row |
113 | \li Door |
114 | \li DOOR_FRAME |
115 | \li Door |
116 | \li The anchor represents a door. |
117 | \row |
118 | \li Other |
119 | \li - |
120 | \li - |
121 | \li The anchor represents something else. See: \l classificationString |
122 | \endtable |
123 | */ |
124 | |
125 | QQuick3DXrSpatialAnchor::QQuick3DXrSpatialAnchor(QtQuick3DXr::XrSpaceId space, QUuid &uuid, QObject *parent) |
126 | : QObject(parent) |
127 | , m_space(space) |
128 | , m_uuid(uuid) |
129 | { |
130 | } |
131 | |
132 | QQuick3DXrSpatialAnchor::~QQuick3DXrSpatialAnchor() |
133 | { |
134 | } |
135 | |
136 | /*! |
137 | \qmlproperty vector3d XrSpatialAnchor::offset3D |
138 | \brief The 3D offset of the spatial anchor. |
139 | \readonly |
140 | |
141 | This property provides the 3D offset of the anchor's bounds (in meters) from the anchor's \l position. |
142 | |
143 | \sa offset3D, has3DBounds |
144 | */ |
145 | |
146 | QVector3D QQuick3DXrSpatialAnchor::offset3D() const |
147 | { |
148 | return m_offset3D; |
149 | } |
150 | |
151 | void QQuick3DXrSpatialAnchor::setOffset3D(const QVector3D &newOffset) |
152 | { |
153 | if (m_offset3D == newOffset) |
154 | return; |
155 | m_offset3D = newOffset; |
156 | emit offset3DChanged(); |
157 | } |
158 | |
159 | /*! |
160 | \qmlproperty vector3d XrSpatialAnchor::extent3D |
161 | \brief The 3D extent of the spatial anchor. |
162 | \readonly |
163 | |
164 | This property specifies the spatial anchor's volume in three dimensions (width, height, and depth). |
165 | It is valid when \l has3DBounds is \c true. |
166 | |
167 | \sa offset3D, has3DBounds |
168 | */ |
169 | |
170 | QVector3D QQuick3DXrSpatialAnchor::extent3D() const |
171 | { |
172 | return m_extent3D; |
173 | } |
174 | |
175 | void QQuick3DXrSpatialAnchor::setExtent3D(const QVector3D &newExtent) |
176 | { |
177 | if (m_extent3D == newExtent) |
178 | return; |
179 | m_extent3D = newExtent; |
180 | emit extent3DChanged(); |
181 | } |
182 | |
183 | /*! |
184 | \qmlproperty vector3d XrSpatialAnchor::position |
185 | \brief The position of the spatial anchor. |
186 | |
187 | \readonly |
188 | This property returns the 3D position (in meters) of the spatial anchor's origin within the |
189 | session's coordinate system. |
190 | */ |
191 | |
192 | QVector3D QQuick3DXrSpatialAnchor::position() const |
193 | { |
194 | return m_position; |
195 | } |
196 | |
197 | void QQuick3DXrSpatialAnchor::setPosition(const QVector3D &newPosition) |
198 | { |
199 | if (m_position == newPosition) |
200 | return; |
201 | m_position = newPosition; |
202 | emit positionChanged(); |
203 | } |
204 | |
205 | /*! |
206 | \qmlproperty quaternion XrSpatialAnchor::rotation |
207 | \brief The orientation of the spatial anchor. |
208 | \readonly |
209 | |
210 | This property provides the spatial anchor's rotation (as a quaternion). |
211 | */ |
212 | |
213 | QQuaternion QQuick3DXrSpatialAnchor::rotation() const |
214 | { |
215 | return m_rotation; |
216 | } |
217 | |
218 | void QQuick3DXrSpatialAnchor::setRotation(const QQuaternion &newRotation) |
219 | { |
220 | if (m_rotation == newRotation) |
221 | return; |
222 | m_rotation = newRotation; |
223 | emit rotationChanged(); |
224 | } |
225 | |
226 | /*! |
227 | \qmlproperty enumeration XrSpatialAnchor::classification |
228 | \brief The classification type of the spatial anchor. |
229 | \readonly |
230 | |
231 | This property returns the \l {XrSpatialAnchor::Classification}{classification type} for this anchor |
232 | (for example,\c Table or \c Floor) describing the anchor's purpose or context. |
233 | |
234 | \note The classification type coming from the system might not be in the set of labels |
235 | defined by the \l Classification enum, in which case the type will be set to \c Other |
236 | and the \l classificationString property will contain the original label. |
237 | |
238 | \sa classificationString |
239 | */ |
240 | |
241 | QQuick3DXrSpatialAnchor::Classification QQuick3DXrSpatialAnchor::classification() const |
242 | { |
243 | return m_classification; |
244 | } |
245 | |
246 | void QQuick3DXrSpatialAnchor::setClassification(Classification newClassification) |
247 | { |
248 | if (m_classification == newClassification) |
249 | return; |
250 | m_classification = newClassification; |
251 | emit classificationChanged(); |
252 | } |
253 | |
254 | /*! |
255 | \qmlproperty string XrSpatialAnchor::classificationString |
256 | \brief The classification type of the spatial anchor as a string. |
257 | \readonly |
258 | |
259 | This property returns the classification type as a string if one exists. |
260 | If the classification type is not in the set of types defined by the \l Classification enums, the |
261 | label is set to \c Other, and this property can be used to access the type as it was reported by |
262 | the system. |
263 | |
264 | \note This string can be empty or change, depending on the system and how the anchor gets classified. |
265 | |
266 | \sa classification |
267 | */ |
268 | |
269 | QString QQuick3DXrSpatialAnchor::classificationString() const |
270 | { |
271 | return m_classificationString; |
272 | } |
273 | |
274 | void QQuick3DXrSpatialAnchor::setClassificationString(const QString &newClassificationString) |
275 | { |
276 | if (m_classificationString == newClassificationString) |
277 | return; |
278 | m_classificationString = newClassificationString; |
279 | emit classificationStringChanged(); |
280 | } |
281 | |
282 | /*! |
283 | \qmlproperty bool XrSpatialAnchor::has2DBounds |
284 | \brief Indicates whether the spatial anchor has 2D bounds. |
285 | \readonly |
286 | |
287 | This property holds \c true if the spatial anchor has 2D bounds, |
288 | described by \l offset2D and \l extent2D, indicating that it |
289 | represents a flat surface (for example, a floor or wall). |
290 | |
291 | Otherwise, it returns false. |
292 | \sa offset2D, extent2D, has3DBounds |
293 | */ |
294 | |
295 | bool QQuick3DXrSpatialAnchor::has2DBounds() const |
296 | { |
297 | return m_has2DBounds; |
298 | } |
299 | |
300 | void QQuick3DXrSpatialAnchor::setBounds2D(const QVector2D &offset, const QVector2D &extent) |
301 | { |
302 | if (qFuzzyCompare(v1: m_offset2D, v2: offset) && qFuzzyCompare(v1: m_extent2D, v2: extent)) |
303 | return; |
304 | |
305 | m_offset2D = offset; |
306 | m_extent2D = extent; |
307 | |
308 | // FIXME: verify |
309 | m_has2DBounds = true; |
310 | |
311 | emit has2DBoundsChanged(); |
312 | } |
313 | |
314 | /*! |
315 | \qmlproperty bool XrSpatialAnchor::has3DBounds |
316 | \brief Indicates whether the spatial anchor has 3D bounds. |
317 | \readonly |
318 | |
319 | This property returns \c true if the spatial anchor has 3D bounds, indicating |
320 | that it represents a volume (for example, a table or a cupboard). |
321 | The bounds are described by \l offset3D and \l extent3D. |
322 | |
323 | Otherwise, it returns \c false. |
324 | \sa offset3D, extent3D, has2DBounds |
325 | */ |
326 | |
327 | |
328 | bool QQuick3DXrSpatialAnchor::has3DBounds() const |
329 | { |
330 | return m_has3DBounds; |
331 | } |
332 | |
333 | void QQuick3DXrSpatialAnchor::setBounds3D(const QVector3D &offset, const QVector3D &extent) |
334 | { |
335 | if (qFuzzyCompare(v1: m_offset3D, v2: offset) && qFuzzyCompare(v1: m_extent3D, v2: extent)) |
336 | return; |
337 | |
338 | m_offset3D = offset; |
339 | m_extent3D = extent; |
340 | |
341 | // FIXME: Store the 3D bounds and verify |
342 | m_has3DBounds = true; |
343 | |
344 | emit has3DBoundsChanged(); |
345 | } |
346 | |
347 | /*! |
348 | \qmlproperty vector2d XrSpatialAnchor::offset2D |
349 | \brief The 2D offset of the spatial anchor. |
350 | |
351 | \readonly |
352 | This property holds the offset of the anchor's bounds within |
353 | the X/Z plane. It is valid when \l has2DBounds is \c true. |
354 | |
355 | \sa has2DBounds, extent2D |
356 | */ |
357 | |
358 | QVector2D QQuick3DXrSpatialAnchor::offset2D() const |
359 | { |
360 | return m_offset2D; |
361 | } |
362 | |
363 | /*! |
364 | \qmlproperty vector2d XrSpatialAnchor::extent2D |
365 | \brief The 2D extent of the spatial anchor. |
366 | \readonly |
367 | |
368 | This property holds the spatial anchor's size in two dimensions (width and height) within |
369 | the X/Z plane. It is valid when \l has2DBounds is \c true. |
370 | |
371 | \sa has2DBounds, offset2D |
372 | */ |
373 | |
374 | QVector2D QQuick3DXrSpatialAnchor::extent2D() const |
375 | { |
376 | return m_extent2D; |
377 | } |
378 | |
379 | /*! |
380 | \qmlproperty string XrSpatialAnchor::identifier |
381 | \brief A unique identifier for this spatial anchor. |
382 | \readonly |
383 | |
384 | This property holds a unique identifier associated with the |
385 | spatial anchor. This is the same identifier referenced by a \l XrSpatialAnchorListModel. |
386 | */ |
387 | |
388 | QString QQuick3DXrSpatialAnchor::identifier() const |
389 | { |
390 | return QString::fromLatin1(ba: m_uuid.toRfc4122()); |
391 | } |
392 | |
393 | QSet<QUuid> QQuick3DXrSpatialAnchor::roomLayoutUuids() const |
394 | { |
395 | return m_roomLayoutUuids; |
396 | } |
397 | |
398 | void QQuick3DXrSpatialAnchor::setRoomLayoutUuids(const QSet<QUuid> &newRoomLayoutUuids) |
399 | { |
400 | m_roomLayoutUuids = newRoomLayoutUuids; |
401 | } |
402 | |
403 | QSet<QUuid> QQuick3DXrSpatialAnchor::spaceContainerUuids() const |
404 | { |
405 | return m_spaceContainerUuids; |
406 | } |
407 | |
408 | void QQuick3DXrSpatialAnchor::setSpaceContainerUuids(const QSet<QUuid> &newSpaceContainerUuids) |
409 | { |
410 | m_spaceContainerUuids = newSpaceContainerUuids; |
411 | } |
412 | |
413 | QT_END_NAMESPACE |
414 |
Definitions
- QQuick3DXrSpatialAnchor
- ~QQuick3DXrSpatialAnchor
- offset3D
- setOffset3D
- extent3D
- setExtent3D
- position
- setPosition
- rotation
- setRotation
- classification
- setClassification
- classificationString
- setClassificationString
- has2DBounds
- setBounds2D
- has3DBounds
- setBounds3D
- offset2D
- extent2D
- identifier
- roomLayoutUuids
- setRoomLayoutUuids
- spaceContainerUuids
Learn Advanced QML with KDAB
Find out more