blob: 4c17d5e24693a3cdb768f8e3b546925896a95c0f [file]
// 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_