blob: ba0f36333cd311923d98d9cad038a169baeeb662 [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "device/vr/openxr/openxr_anchor_manager.h"
#include <set>
#include <utility>
#include "base/trace_event/trace_event.h"
#include "device/vr/openxr/openxr_api_wrapper.h"
#include "device/vr/openxr/openxr_util.h"
#include "device/vr/public/mojom/pose.h"
#include "device/vr/public/mojom/xr_session.mojom-shared.h"
#include "third_party/openxr/src/include/openxr/openxr.h"
namespace device {
OpenXrAnchorManager::OpenXrAnchorManager() = default;
OpenXrAnchorManager::~OpenXrAnchorManager() {
DisposeActiveAnchorCallbacks();
}
void OpenXrAnchorManager::AddCreateAnchorRequest(
const mojom::XRNativeOriginInformation& native_origin_information,
const device::Pose& native_origin_from_anchor,
const std::optional<PlaneId>& plane_id,
CreateAnchorCallback callback) {
create_anchor_requests_.emplace_back(native_origin_information,
native_origin_from_anchor.ToTransform(),
plane_id, std::move(callback));
}
device::mojom::XRAnchorsDataPtr OpenXrAnchorManager::ProcessAnchorsForFrame(
OpenXrApiWrapper* openxr,
const std::vector<mojom::XRInputSourceStatePtr>& input_state,
XrTime predicted_display_time) {
TRACE_EVENT0("xr", "ProcessAnchorsForFrame");
ProcessCreateAnchorRequests(openxr, input_state);
return GetCurrentAnchorsData(predicted_display_time);
}
void OpenXrAnchorManager::ProcessCreateAnchorRequests(
OpenXrApiWrapper* openxr,
const std::vector<mojom::XRInputSourceStatePtr>& input_state) {
XrTime display_time = openxr->GetPredictedDisplayTime();
for (auto& request : create_anchor_requests_) {
std::optional<XrLocation> anchor_location =
GetXrLocationFromNativeOriginInformation(
openxr, request.GetNativeOriginInformation(),
request.GetNativeOriginFromAnchor(), input_state);
if (!anchor_location.has_value()) {
request.TakeCallback().Run(std::nullopt);
continue;
}
AnchorId anchor_id =
CreateAnchor(anchor_location->pose, anchor_location->space,
display_time, request.GetPlaneId());
request.TakeCallback().Run(anchor_id);
}
create_anchor_requests_.clear();
}
void OpenXrAnchorManager::DisposeActiveAnchorCallbacks() {
for (auto& create_anchor : create_anchor_requests_) {
create_anchor.TakeCallback().Run(std::nullopt);
}
create_anchor_requests_.clear();
}
std::optional<OpenXrAnchorManager::XrLocation>
OpenXrAnchorManager::GetXrLocationFromNativeOriginInformation(
OpenXrApiWrapper* openxr,
const mojom::XRNativeOriginInformation& native_origin_information,
const gfx::Transform& native_origin_from_anchor,
const std::vector<mojom::XRInputSourceStatePtr>& input_state) const {
switch (native_origin_information.which()) {
case mojom::XRNativeOriginInformation::Tag::kInputSourceSpaceInfo:
// Currently unimplemented as only anchors are supported and are never
// created relative to input sources
return std::nullopt;
case mojom::XRNativeOriginInformation::Tag::kReferenceSpaceType:
return GetXrLocationFromReferenceSpace(openxr, native_origin_information,
native_origin_from_anchor);
case mojom::XRNativeOriginInformation::Tag::kHandJointSpaceInfo:
case mojom::XRNativeOriginInformation::Tag::kImageIndex:
// Unsupported for now
return std::nullopt;
case mojom::XRNativeOriginInformation::Tag::kAnchorId:
return GetXrLocationFromAnchor(native_origin_information.get_anchor_id(),
native_origin_from_anchor);
case mojom::XRNativeOriginInformation::Tag::kPlaneId:
return GetXrLocationFromPlane(native_origin_information.get_plane_id(),
native_origin_from_anchor);
}
}
std::optional<OpenXrAnchorManager::XrLocation>
OpenXrAnchorManager::GetXrLocationFromReferenceSpace(
OpenXrApiWrapper* openxr,
const mojom::XRNativeOriginInformation& native_origin_information,
const gfx::Transform& native_origin_from_anchor) const {
return XrLocation{GfxTransformToXrPose(native_origin_from_anchor),
openxr->GetReferenceSpace(
native_origin_information.get_reference_space_type())};
}
} // namespace device