Skyscraper 2.0
XrSceneUnderstanding.hpp
Go to the documentation of this file.
1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4#pragma once
5
6#include <optional>
7#include <XrUtility/XrUuid.h>
9
10// C++ wrapper on the OpenXR Scene Understanding extension.
11namespace xr::su {
12 struct SceneObject { // XR_SCENE_COMPONENT_TYPE_OBJECT_MSFT
14 using Type = ::XrSceneObjectTypeMSFT;
17 XrTime updateTime;
19 };
20
21 struct ScenePlane { // XR_SCENE_COMPONENT_TYPE_PLANE_MSFT
23 using Alignment = ::XrScenePlaneAlignmentTypeMSFT;
24 using Extent = XrExtent2Df;
27 XrTime updateTime;
30 uint64_t meshBufferId;
32 };
33
34 struct SceneMesh { // XR_SCENE_COMPONENT_TYPE_VISUAL_MESH_MSFT
38 XrTime updateTime;
39 uint64_t meshBufferId;
41 };
42
43 struct SceneColliderMesh { // XR_SCENE_COMPONENT_TYPE_COLLIDER_MESH_MSFT
47 XrTime updateTime;
48 uint64_t meshBufferId;
50 };
51
52 // Gets the list of scene objects in the scene.
53 // If filterObjectType is not empty then only the scene objects that match any of the given types will be returned.
54 inline std::vector<SceneObject> GetSceneObjects(XrSceneMSFT scene, const std::vector<SceneObject::Type>& filterObjectType = {}) {
55 XrSceneComponentsGetInfoMSFT getInfo{XR_TYPE_SCENE_COMPONENTS_GET_INFO_MSFT};
56 getInfo.componentType = XR_SCENE_COMPONENT_TYPE_OBJECT_MSFT;
57
58 XrSceneObjectTypesFilterInfoMSFT typesFilter{XR_TYPE_SCENE_OBJECT_TYPES_FILTER_INFO_MSFT};
59 if (!filterObjectType.empty()) {
60 typesFilter.objectTypeCount = static_cast<uint32_t>(filterObjectType.size());
61 typesFilter.objectTypes = filterObjectType.data();
62 xr::InsertExtensionStruct(getInfo, typesFilter);
63 }
64
65 XrSceneComponentsMSFT sceneComponents{XR_TYPE_SCENE_COMPONENTS_MSFT};
66 CHECK_XRCMD(xrGetSceneComponentsMSFT(scene, &getInfo, &sceneComponents));
67 const uint32_t count = sceneComponents.componentCountOutput;
68
69 std::vector<XrSceneComponentMSFT> components(count);
70 sceneComponents.componentCapacityInput = count;
71 sceneComponents.components = components.data();
72
73 std::vector<XrSceneObjectMSFT> objects(count);
74 XrSceneObjectsMSFT sceneObjects{XR_TYPE_SCENE_OBJECTS_MSFT};
75 sceneObjects.sceneObjectCount = count;
76 sceneObjects.sceneObjects = objects.data();
77 xr::InsertExtensionStruct(sceneComponents, sceneObjects);
78
79 CHECK_XRCMD(xrGetSceneComponentsMSFT(scene, &getInfo, &sceneComponents));
80
81 std::vector<SceneObject> result(count);
82 for (uint32_t k = 0; k < count; k++) {
83 result[k].id = components[k].id;
84 result[k].updateTime = components[k].updateTime;
85 result[k].type = objects[k].objectType;
86 }
87 return result;
88 }
89
90 // Gets the list of scene planes in the scene.
91 // - If parentId is set then only the scene planes that are children of that scene object will be returned.
92 // - If filterObjectType is not empty then only the scene planes that match any of the given types will be returned.
93 // - If filterAlignment is not empty then only the scene planes that match any of the given alignments will be returned.
94 // - If filterObjectType and filterAlignment are not empty then the scene plane must pass both filters.
95 inline std::vector<ScenePlane> GetScenePlanes(XrSceneMSFT scene,
96 std::optional<SceneObject::Id> parentId = {},
97 const std::vector<SceneObject::Type>& filterObjectType = {},
98 const std::vector<ScenePlane::Alignment>& filterAlignment = {}) {
99 XrSceneComponentsGetInfoMSFT getInfo{XR_TYPE_SCENE_COMPONENTS_GET_INFO_MSFT};
100 getInfo.componentType = XR_SCENE_COMPONENT_TYPE_PLANE_MSFT;
101
102 XrSceneComponentParentFilterInfoMSFT parentFilter{XR_TYPE_SCENE_COMPONENT_PARENT_FILTER_INFO_MSFT};
103 if (parentId.has_value()) {
104 parentFilter.parentId = static_cast<XrUuidMSFT>(parentId.value());
105 xr::InsertExtensionStruct(getInfo, parentFilter);
106 }
107
108 XrSceneObjectTypesFilterInfoMSFT typesFilter{XR_TYPE_SCENE_OBJECT_TYPES_FILTER_INFO_MSFT};
109 if (!filterObjectType.empty()) {
110 typesFilter.objectTypeCount = static_cast<uint32_t>(filterObjectType.size());
111 typesFilter.objectTypes = filterObjectType.data();
112 xr::InsertExtensionStruct(getInfo, typesFilter);
113 }
114
115 XrScenePlaneAlignmentFilterInfoMSFT alignmentFilter{XR_TYPE_SCENE_PLANE_ALIGNMENT_FILTER_INFO_MSFT};
116 if (!filterAlignment.empty()) {
117 alignmentFilter.alignmentCount = static_cast<uint32_t>(filterAlignment.size());
118 alignmentFilter.alignments = filterAlignment.data();
119 xr::InsertExtensionStruct(getInfo, alignmentFilter);
120 }
121
122 XrSceneComponentsMSFT sceneComponents{XR_TYPE_SCENE_COMPONENTS_MSFT};
123 CHECK_XRCMD(xrGetSceneComponentsMSFT(scene, &getInfo, &sceneComponents));
124 const uint32_t count = sceneComponents.componentCountOutput;
125
126 std::vector<XrSceneComponentMSFT> components(count);
127 sceneComponents.componentCapacityInput = count;
128 sceneComponents.components = components.data();
129
130 std::vector<XrScenePlaneMSFT> planes(count);
131 XrScenePlanesMSFT scenePlanes{XR_TYPE_SCENE_PLANES_MSFT};
132 scenePlanes.scenePlaneCount = count;
133 scenePlanes.scenePlanes = planes.data();
134 xr::InsertExtensionStruct(sceneComponents, scenePlanes);
135
136 CHECK_XRCMD(xrGetSceneComponentsMSFT(scene, &getInfo, &sceneComponents));
137
138 std::vector<ScenePlane> result(count);
139 for (uint32_t k = 0; k < count; k++) {
140 result[k].id = components[k].id;
141 result[k].parentId = components[k].parentId;
142 result[k].updateTime = components[k].updateTime;
143 result[k].alignment = planes[k].alignment;
144 result[k].size = planes[k].size;
145 result[k].meshBufferId = planes[k].meshBufferId;
146 result[k].supportsIndicesUint16 = planes[k].supportsIndicesUint16;
147 }
148 return result;
149 }
150
151 // Gets the list of scene visual meshes in the scene.
152 // - If parentId is set then only the scene meshes that are children of that scene object will be returned.
153 // - If filterObjectType is not empty then only the scene objects that match any of the given types will be returned.
154 inline std::vector<SceneMesh> GetSceneVisualMeshes(XrSceneMSFT scene,
155 std::optional<SceneObject::Id> parentId = {},
156 const std::vector<SceneObject::Type>& filterObjectType = {}) {
157 XrSceneComponentsGetInfoMSFT getInfo{XR_TYPE_SCENE_COMPONENTS_GET_INFO_MSFT};
158 getInfo.componentType = XR_SCENE_COMPONENT_TYPE_VISUAL_MESH_MSFT;
159
160 XrSceneComponentParentFilterInfoMSFT parentFilter{XR_TYPE_SCENE_COMPONENT_PARENT_FILTER_INFO_MSFT};
161 if (parentId.has_value()) {
162 parentFilter.parentId = static_cast<XrUuidMSFT>(parentId.value());
163 xr::InsertExtensionStruct(getInfo, parentFilter);
164 }
165
166 XrSceneObjectTypesFilterInfoMSFT typesFilter{XR_TYPE_SCENE_OBJECT_TYPES_FILTER_INFO_MSFT};
167 if (!filterObjectType.empty()) {
168 typesFilter.objectTypeCount = static_cast<uint32_t>(filterObjectType.size());
169 typesFilter.objectTypes = filterObjectType.data();
170 xr::InsertExtensionStruct(getInfo, typesFilter);
171 }
172
173 XrSceneComponentsMSFT sceneComponents{XR_TYPE_SCENE_COMPONENTS_MSFT};
174 CHECK_XRCMD(xrGetSceneComponentsMSFT(scene, &getInfo, &sceneComponents));
175 const uint32_t count = sceneComponents.componentCountOutput;
176
177 std::vector<XrSceneComponentMSFT> components(count);
178 sceneComponents.componentCapacityInput = count;
179 sceneComponents.components = components.data();
180
181 std::vector<XrSceneMeshMSFT> meshes(count);
182 XrSceneMeshesMSFT sceneMeshes{XR_TYPE_SCENE_MESHES_MSFT};
183 sceneMeshes.sceneMeshCount = count;
184 sceneMeshes.sceneMeshes = meshes.data();
185 xr::InsertExtensionStruct(sceneComponents, sceneMeshes);
186
187 CHECK_XRCMD(xrGetSceneComponentsMSFT(scene, &getInfo, &sceneComponents));
188
189 std::vector<SceneMesh> result(count);
190 for (uint32_t k = 0; k < count; k++) {
191 result[k].id = components[k].id;
192 result[k].parentId = components[k].parentId;
193 result[k].updateTime = components[k].updateTime;
194 result[k].meshBufferId = meshes[k].meshBufferId;
195 result[k].supportsIndicesUint16 = meshes[k].supportsIndicesUint16;
196 }
197 return result;
198 }
199
200 inline std::vector<SceneColliderMesh> GetSceneColliderMeshes(XrSceneMSFT scene,
201 std::optional<SceneObject::Id> parentId = {},
202 const std::vector<SceneObject::Type>& filterObjectType = {}) {
203 XrSceneComponentsGetInfoMSFT getInfo{XR_TYPE_SCENE_COMPONENTS_GET_INFO_MSFT};
204 getInfo.componentType = XR_SCENE_COMPONENT_TYPE_COLLIDER_MESH_MSFT;
205
206 XrSceneComponentParentFilterInfoMSFT parentFilter{XR_TYPE_SCENE_COMPONENT_PARENT_FILTER_INFO_MSFT};
207 if (parentId.has_value()) {
208 parentFilter.parentId = static_cast<XrUuidMSFT>(parentId.value());
209 xr::InsertExtensionStruct(getInfo, parentFilter);
210 }
211
212 XrSceneObjectTypesFilterInfoMSFT typesFilter{XR_TYPE_SCENE_OBJECT_TYPES_FILTER_INFO_MSFT};
213 if (!filterObjectType.empty()) {
214 typesFilter.objectTypeCount = static_cast<uint32_t>(filterObjectType.size());
215 typesFilter.objectTypes = filterObjectType.data();
216 xr::InsertExtensionStruct(getInfo, typesFilter);
217 }
218
219 XrSceneComponentsMSFT sceneComponents{XR_TYPE_SCENE_COMPONENTS_MSFT};
220 CHECK_XRCMD(xrGetSceneComponentsMSFT(scene, &getInfo, &sceneComponents));
221 const uint32_t count = sceneComponents.componentCountOutput;
222
223 std::vector<XrSceneComponentMSFT> components(count);
224 sceneComponents.componentCapacityInput = count;
225 sceneComponents.components = components.data();
226
227 std::vector<XrSceneMeshMSFT> meshes(count);
228 XrSceneMeshesMSFT sceneMeshes{XR_TYPE_SCENE_MESHES_MSFT};
229 sceneMeshes.sceneMeshCount = count;
230 sceneMeshes.sceneMeshes = meshes.data();
231 xr::InsertExtensionStruct(sceneComponents, sceneMeshes);
232
233 CHECK_XRCMD(xrGetSceneComponentsMSFT(scene, &getInfo, &sceneComponents));
234
235 std::vector<SceneColliderMesh> result(count);
236 for (uint32_t k = 0; k < count; k++) {
237 result[k].id = components[k].id;
238 result[k].parentId = components[k].parentId;
239 result[k].updateTime = components[k].updateTime;
240 result[k].meshBufferId = meshes[k].meshBufferId;
241 result[k].supportsIndicesUint16 = meshes[k].supportsIndicesUint16;
242 }
243 return result;
244 }
245
246 // Locate components given space and time.
247 template <typename TUuid>
248 void LocateObjects(XrSceneMSFT scene,
249 XrSpace baseSpace,
250 XrTime time,
251 const std::vector<TUuid>& componentIds,
252 std::vector<XrSceneComponentLocationMSFT>& locations) {
253 XrSceneComponentsLocateInfoMSFT locateInfo{XR_TYPE_SCENE_COMPONENTS_LOCATE_INFO_MSFT};
254 locateInfo.baseSpace = baseSpace;
255 locateInfo.time = time;
256 locateInfo.componentIdCount = static_cast<uint32_t>(componentIds.size());
257 static_assert(sizeof(TUuid) == sizeof(XrUuidMSFT));
258 locateInfo.componentIds = static_cast<const XrUuidMSFT*>(componentIds.data());
259
260 locations.resize(componentIds.size());
261 XrSceneComponentLocationsMSFT componentLocations{XR_TYPE_SCENE_COMPONENT_LOCATIONS_MSFT};
262 componentLocations.locationCount = static_cast<uint32_t>(locations.size());
263 componentLocations.locations = locations.data();
264
265 CHECK_XRCMD(xrLocateSceneComponentsMSFT(scene, &locateInfo, &componentLocations));
266 }
267
268 // C++ wrapper for XrSceneMSFT
269 struct Scene {
270 Scene(XrSceneObserverMSFT sceneObserver)
271 : m_scene(xr::CreateScene(sceneObserver)) {
272 }
273
274 // Gets the scene objects in this scene.
275 inline std::vector<SceneObject> GetObjects(const std::vector<SceneObject::Type>& filterObjectType = {}) const {
276 return GetSceneObjects(m_scene.Get(), filterObjectType);
277 }
278
279 inline std::vector<ScenePlane> GetPlanes(const std::vector<SceneObject::Type>& filterObjectType = {},
280 const std::vector<ScenePlane::Alignment>& filterAlignment = {}) const {
281 return GetScenePlanes(m_scene.Get(), {}, filterObjectType, filterAlignment);
282 }
283
284 inline std::vector<SceneMesh> GetVisualMeshes(const std::vector<SceneObject::Type>& filterObjectType = {}) const {
285 return GetSceneVisualMeshes(m_scene.Get(), {}, filterObjectType);
286 }
287
288 inline std::vector<SceneColliderMesh> GetColliderMeshes(const std::vector<SceneObject::Type>& filterObjectType = {}) const {
289 return GetSceneColliderMeshes(m_scene.Get(), {}, filterObjectType);
290 }
291
292 inline std::vector<ScenePlane> GetChildrenPlanes(SceneObject::Id parentId,
293 const std::vector<SceneObject::Type>& filterObjectType = {},
294 const std::vector<ScenePlane::Alignment>& filterAlignment = {}) const {
295 return GetScenePlanes(m_scene.Get(), parentId, filterObjectType, filterAlignment);
296 }
297
298 inline std::vector<SceneMesh> GetChildrenVisualMeshes(SceneObject::Id parentId,
299 const std::vector<SceneObject::Type>& filterObjectType = {}) const {
300 return GetSceneVisualMeshes(m_scene.Get(), parentId, filterObjectType);
301 }
302
303 inline std::vector<SceneColliderMesh> GetChildrenColliderMeshes(SceneObject::Id parentId,
304 const std::vector<SceneObject::Type>& filterObjectType = {}) const {
305 return GetSceneColliderMeshes(m_scene.Get(), parentId, filterObjectType);
306 }
307
308 inline XrSceneMSFT Handle() const noexcept {
309 return m_scene.Get();
310 }
311
312 private:
314 };
315
316 // C++ wrapper for XrSceneObserverMSFT
318 SceneObserver(XrSession session)
320 }
321
322 inline void ComputeNewScene(const std::vector<XrSceneComputeFeatureMSFT>& requestedFeatures,
323 const SceneBounds& bounds,
324 XrSceneComputeConsistencyMSFT consistency = XR_SCENE_COMPUTE_CONSISTENCY_SNAPSHOT_COMPLETE_MSFT,
325 std::optional<XrMeshComputeLodMSFT> visualMeshLevelOfDetail = {}) const {
326 xr::ComputeNewScene(m_sceneObserver.Get(), requestedFeatures, bounds, consistency, visualMeshLevelOfDetail);
327 }
328
329 inline XrSceneComputeStateMSFT GetSceneComputeState() const {
330 XrSceneComputeStateMSFT state{XR_SCENE_COMPUTE_STATE_NONE_MSFT};
331 CHECK_XRCMD(xrGetSceneComputeStateMSFT(m_sceneObserver.Get(), &state));
332 return state;
333 }
334
335 inline bool IsSceneComputeCompleted() const {
336 const XrSceneComputeStateMSFT state = GetSceneComputeState();
337 return state == XR_SCENE_COMPUTE_STATE_COMPLETED_MSFT || state == XR_SCENE_COMPUTE_STATE_COMPLETED_WITH_ERROR_MSFT;
338 }
339
340 inline std::unique_ptr<Scene> CreateScene() const {
341 return std::make_unique<Scene>(m_sceneObserver.Get());
342 }
343
344 inline XrSceneObserverMSFT Handle() const noexcept {
345 return m_sceneObserver.Get();
346 }
347
348 private:
350 };
351} // namespace xr::su
#define CHECK_XRCMD(cmd)
Definition XrError.h:14
HandleType Get() const noexcept
Definition XrHandle.h:51
void LocateObjects(XrSceneMSFT scene, XrSpace baseSpace, XrTime time, const std::vector< TUuid > &componentIds, std::vector< XrSceneComponentLocationMSFT > &locations)
std::vector< ScenePlane > GetScenePlanes(XrSceneMSFT scene, std::optional< SceneObject::Id > parentId={}, const std::vector< SceneObject::Type > &filterObjectType={}, const std::vector< ScenePlane::Alignment > &filterAlignment={})
std::vector< SceneMesh > GetSceneVisualMeshes(XrSceneMSFT scene, std::optional< SceneObject::Id > parentId={}, const std::vector< SceneObject::Type > &filterObjectType={})
std::vector< SceneObject > GetSceneObjects(XrSceneMSFT scene, const std::vector< SceneObject::Type > &filterObjectType={})
std::vector< SceneColliderMesh > GetSceneColliderMeshes(XrSceneMSFT scene, std::optional< SceneObject::Id > parentId={}, const std::vector< SceneObject::Type > &filterObjectType={})
The xr::DispatchTable struct contains all available PFN pointers to xr functions including those in a...
void InsertExtensionStruct(XrStruct &xrStruct, XrExtension &xrExtension)
Definition XrStruct.h:43
xr::SceneObserverHandle CreateSceneObserver(XrSession session)
void ComputeNewScene(XrSceneObserverMSFT sceneObserver, const std::vector< XrSceneComputeFeatureMSFT > &requestedFeatures, const SceneBounds &bounds, XrSceneComputeConsistencyMSFT consistency=XR_SCENE_COMPUTE_CONSISTENCY_SNAPSHOT_COMPLETE_MSFT, std::optional< XrMeshComputeLodMSFT > visualMeshLevelOfDetail={})
xr::SceneHandle CreateScene(XrSceneObserverMSFT sceneObserver)
::XrSceneObjectTypeMSFT Type
SceneObserver(XrSession session)
void ComputeNewScene(const std::vector< XrSceneComputeFeatureMSFT > &requestedFeatures, const SceneBounds &bounds, XrSceneComputeConsistencyMSFT consistency=XR_SCENE_COMPUTE_CONSISTENCY_SNAPSHOT_COMPLETE_MSFT, std::optional< XrMeshComputeLodMSFT > visualMeshLevelOfDetail={}) const
XrSceneObserverMSFT Handle() const noexcept
xr::SceneObserverHandle m_sceneObserver
XrSceneComputeStateMSFT GetSceneComputeState() const
std::unique_ptr< Scene > CreateScene() const
::XrScenePlaneAlignmentTypeMSFT Alignment
xr::SceneHandle m_scene
std::vector< ScenePlane > GetPlanes(const std::vector< SceneObject::Type > &filterObjectType={}, const std::vector< ScenePlane::Alignment > &filterAlignment={}) const
std::vector< SceneColliderMesh > GetChildrenColliderMeshes(SceneObject::Id parentId, const std::vector< SceneObject::Type > &filterObjectType={}) const
std::vector< SceneObject > GetObjects(const std::vector< SceneObject::Type > &filterObjectType={}) const
std::vector< ScenePlane > GetChildrenPlanes(SceneObject::Id parentId, const std::vector< SceneObject::Type > &filterObjectType={}, const std::vector< ScenePlane::Alignment > &filterAlignment={}) const
Scene(XrSceneObserverMSFT sceneObserver)
std::vector< SceneMesh > GetChildrenVisualMeshes(SceneObject::Id parentId, const std::vector< SceneObject::Type > &filterObjectType={}) const
std::vector< SceneMesh > GetVisualMeshes(const std::vector< SceneObject::Type > &filterObjectType={}) const
std::vector< SceneColliderMesh > GetColliderMeshes(const std::vector< SceneObject::Type > &filterObjectType={}) const
XrSceneMSFT Handle() const noexcept