| // Copyright 2025 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef DEVICE_VR_OPENXR_OPENXR_SPATIAL_PLANE_MANAGER_H_ |
| #define DEVICE_VR_OPENXR_OPENXR_SPATIAL_PLANE_MANAGER_H_ |
| |
| #include <vector> |
| |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "device/vr/openxr/openxr_extension_helper.h" |
| #include "device/vr/openxr/openxr_mesh_manager.h" |
| #include "device/vr/openxr/openxr_plane_manager.h" |
| #include "device/vr/public/mojom/mesh_id.h" |
| #include "third_party/abseil-cpp/absl/container/flat_hash_map.h" |
| #include "third_party/abseil-cpp/absl/container/flat_hash_set.h" |
| #include "third_party/openxr/src/include/openxr/openxr.h" |
| |
| namespace device { |
| |
| class OpenXrExtensionHelper; |
| class OpenXrSpatialFrameworkManager; |
| |
| // Delegate class for OpenXrSpatialFrameworkManager responsible for integration |
| // with the XR_EXT_SPATIAL_PLANE_TRACKING extension. Also synthesizes mesh data |
| // from plane tracking entities to support the mesh detection feature. |
| class OpenXrSpatialPlaneManager : public OpenXrPlaneManager, |
| public OpenXrMeshManager { |
| public: |
| // Queries the supported spatial capabilities and spatial components on the |
| // current system instance and returns whether or not this manager can be |
| // enabled to provide support for the plane detection feature. |
| static bool IsSupported( |
| const std::vector<XrSpatialCapabilityEXT>& capabilities); |
| |
| OpenXrSpatialPlaneManager( |
| XrSpace mojo_space, |
| const OpenXrExtensionHelper& extension_helper, |
| const OpenXrSpatialFrameworkManager& framework_manager, |
| XrInstance instance, |
| XrSystemId system, |
| bool mesh_detection_enabled); |
| ~OpenXrSpatialPlaneManager() override; |
| |
| // Mutates the provided map to fill in the necessary capabilities and |
| // components for those capabilities that need to be enabled. Used to build |
| // the list of |capabilityConfigs| on the |XrSpatialContextCreateInfoEXT| used |
| // to create the spatial context. |
| void PopulateCapabilityConfiguration( |
| absl::flat_hash_map<XrSpatialCapabilityEXT, |
| absl::flat_hash_set<XrSpatialComponentTypeEXT>>& |
| capability_configuration) const; |
| |
| void OnSnapshotChanged(); |
| mojom::XRPlaneDetectionDataPtr GetDetectedPlanesData() override; |
| std::optional<device::Pose> TryGetMojoFromPlane(PlaneId plane_id) const; |
| |
| // Return the `PlaneId` of the corresponding |entity_id|. Will return |
| // |kInvalidPlaneId| if the entity is not currently tracked. |
| PlaneId GetPlaneId(XrSpatialEntityIdEXT entity_id) const; |
| |
| std::optional<XrLocation> GetXrLocationFromPlane( |
| PlaneId plane_id, |
| const gfx::Transform& plane_id_from_object) const override; |
| |
| // OpenXrMeshManager implementation. |
| mojom::XRMeshDetectionDataPtr GetDetectedMeshesData( |
| XrTime frame_time, |
| XrSpace view_space) override; |
| std::optional<XrLocation> GetXrLocationFromMesh( |
| MeshId mesh_id, |
| const gfx::Transform& mesh_id_from_object) const override; |
| void OnReferenceSpaceChanged() override; |
| |
| std::optional<device::Pose> TryGetMojoFromMesh(MeshId mesh_id) const; |
| MeshId GetMeshId(XrSpatialEntityIdEXT entity_id) const; |
| |
| // Return the `XrSpatialEntityIdEXT` of the corresponding |plane_id|. Will |
| // return XR_NULL_SPATIAL_ENTITY_ID_EXT if the |plane_id| is not currently |
| // tracked or otherwise invalid. |
| XrSpatialEntityIdEXT GetEntityId(PlaneId plane_id) const; |
| |
| bool can_parent_anchors() const { return can_parent_anchors_; } |
| bool mesh_detection_enabled() const { return mesh_detection_enabled_; } |
| |
| private: |
| bool GetPolygonFromBuffer(XrSpatialSnapshotEXT snapshot, |
| const XrSpatialPolygon2DDataEXT& polygon_data, |
| mojom::XRPlaneDataPtr& plane_data) const; |
| |
| void GetPolygonFromExtent(const XrSpatialBounded2DDataEXT& bounded_2d_data, |
| mojom::XRPlaneDataPtr& plane_data) const; |
| |
| XrSpatialEntityIdEXT GetMeshEntityId(MeshId mesh_id) const; |
| |
| XrSpace mojo_space_; |
| const raw_ref<const OpenXrExtensionHelper> extension_helper_; |
| const raw_ref<const OpenXrSpatialFrameworkManager> framework_manager_; |
| |
| // Plane data. |
| absl::flat_hash_map<XrSpatialEntityIdEXT, mojom::XRPlaneDataPtr> |
| entity_id_to_data_; |
| absl::flat_hash_set<XrSpatialEntityIdEXT> updated_entity_ids_; |
| |
| // Mesh data synthesized from plane tracking entities. |
| bool mesh_detection_enabled_ = false; |
| absl::flat_hash_map<XrSpatialEntityIdEXT, mojom::XRMeshDataPtr> |
| mesh_entity_id_to_data_; |
| absl::flat_hash_set<XrSpatialEntityIdEXT> mesh_updated_entity_ids_; |
| |
| bool can_parent_anchors_ = false; |
| |
| absl::flat_hash_set<XrSpatialComponentTypeEXT> enabled_components_; |
| bool polygon_enabled_ = false; |
| bool semantic_label_enabled_ = false; |
| |
| base::WeakPtrFactory<OpenXrSpatialPlaneManager> weak_ptr_factory_{this}; |
| }; |
| |
| } // namespace device |
| |
| #endif // DEVICE_VR_OPENXR_OPENXR_SPATIAL_PLANE_MANAGER_H_ |