Commit e18bb0f7 authored by Piotr Bialecki's avatar Piotr Bialecki Committed by Commit Bot

Implement anchor creation from XRSession and XRPlane

Bug: 992033
Change-Id: I5d79658062e574b7c910af03b0ec0c838c169f05
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1774659
Auto-Submit: Piotr Bialecki <bialpio@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarKlaus Weidner <klausw@chromium.org>
Commit-Queue: Piotr Bialecki <bialpio@chromium.org>
Cr-Commit-Position: refs/heads/master@{#695250}
parent 8a22cc26
......@@ -10,6 +10,7 @@
#include "base/android/scoped_java_ref.h"
#include "base/macros.h"
#include "base/optional.h"
#include "device/vr/public/mojom/vr_service.mojom.h"
#include "ui/display/display.h"
#include "ui/gfx/transform.h"
......@@ -54,6 +55,13 @@ class ArCore {
const mojom::XRRayPtr& ray,
std::vector<mojom::XRHitResultPtr>* hit_results) = 0;
virtual base::Optional<int32_t> CreateAnchor(
const mojom::VRPosePtr& pose) = 0;
virtual base::Optional<int32_t> CreateAnchor(const mojom::VRPosePtr& pose,
int32_t plane_id) = 0;
virtual void DetachAnchor(int32_t anchor_id) = 0;
virtual void Pause() = 0;
virtual void Resume() = 0;
};
......
......@@ -583,6 +583,42 @@ void ArCoreGl::RequestHitTest(
hit_test_requests_.push_back(std::move(request));
}
void ArCoreGl::CreateAnchor(mojom::VRPosePtr anchor_pose,
CreateAnchorCallback callback) {
DVLOG(2) << __func__;
base::Optional<int32_t> maybe_anchor_id = arcore_->CreateAnchor(anchor_pose);
if (maybe_anchor_id) {
std::move(callback).Run(device::mojom::CreateAnchorResult::SUCCESS,
*maybe_anchor_id);
} else {
std::move(callback).Run(device::mojom::CreateAnchorResult::FAILURE, 0);
}
}
void ArCoreGl::CreatePlaneAnchor(mojom::VRPosePtr anchor_pose,
int32_t plane_id,
CreatePlaneAnchorCallback callback) {
DVLOG(2) << __func__;
base::Optional<int32_t> maybe_anchor_id =
arcore_->CreateAnchor(anchor_pose, plane_id);
if (maybe_anchor_id) {
std::move(callback).Run(device::mojom::CreateAnchorResult::SUCCESS,
*maybe_anchor_id);
} else {
std::move(callback).Run(device::mojom::CreateAnchorResult::FAILURE, 0);
}
}
void ArCoreGl::DetachAnchor(int32_t anchor_id) {
DVLOG(2) << __func__;
arcore_->DetachAnchor(anchor_id);
}
void ArCoreGl::SetFrameDataRestricted(bool frame_data_restricted) {
DCHECK(IsOnGlThread());
DCHECK(is_initialized_);
......
......@@ -108,6 +108,14 @@ class ArCoreGl : public mojom::XRFrameDataProvider,
mojom::XRRayPtr,
mojom::XREnvironmentIntegrationProvider::RequestHitTestCallback) override;
void CreateAnchor(mojom::VRPosePtr anchor_pose,
CreateAnchorCallback callback) override;
void CreatePlaneAnchor(mojom::VRPosePtr anchor_pose,
int32_t plane_id,
CreatePlaneAnchorCallback callback) override;
void DetachAnchor(int32_t anchor_id) override;
// mojom::XRSessionController
void SetFrameDataRestricted(bool restricted) override;
......
......@@ -37,6 +37,36 @@ device::mojom::VRPosePtr GetMojomPoseFromArPose(
return result;
}
device::internal::ScopedArCoreObject<ArPose*> GetArPoseFromMojomPose(
ArSession* session,
const device::mojom::VRPosePtr& pose) {
float pose_raw[7] = {}; // 7 = orientation(4) + position(3).
if (pose->orientation) {
pose_raw[0] = pose->orientation->x();
pose_raw[1] = pose->orientation->y();
pose_raw[2] = pose->orientation->z();
pose_raw[3] = pose->orientation->w();
} else {
// Only need to set the .w to 1.
pose_raw[3] = 1;
}
if (pose->position) {
pose_raw[4] = pose->position->x();
pose_raw[5] = pose->position->y();
pose_raw[6] = pose->position->z();
}
device::internal::ScopedArCoreObject<ArPose*> result;
ArPose_create(
session, pose_raw,
device::internal::ScopedArCoreObject<ArPose*>::Receiver(result).get());
return result;
}
} // namespace
namespace device {
......@@ -259,7 +289,7 @@ void ArCoreImpl::ForEachArCorePlane(FunctionType fn) {
continue;
}
fn(ar_plane);
fn(std::move(trackable), ar_plane);
}
} // namespace device
......@@ -293,6 +323,10 @@ std::vector<mojom::XRAnchorDataPtr> ArCoreImpl::GetUpdatedAnchorsData() {
bool created;
std::tie(anchor_id, created) = *maybe_anchor_id_and_created;
DCHECK(!created)
<< "Anchor creation is app-initiated - we should never encounter an "
"anchor that was created outside of `ArCoreImpl::CreateAnchor()`.";
result.push_back(mojom::XRAnchorData::New(anchor_id, std::move(pose)));
});
......@@ -319,9 +353,9 @@ std::vector<int32_t> ArCoreImpl::GetAllAnchorIds() {
bool created;
std::tie(anchor_id, created) = *maybe_anchor_id_and_created;
// TODO(https://crbug.com/992033): Add explanation for the below DCHECK when
// implementing anchor creation.
DCHECK(!created);
DCHECK(!created)
<< "Anchor creation is app-initiated - we should never encounter an "
"anchor that was created outside of `ArCoreImpl::CreateAnchor()`.";
result.emplace_back(anchor_id);
});
......@@ -365,7 +399,9 @@ std::vector<mojom::XRPlaneDataPtr> ArCoreImpl::GetUpdatedPlanesData() {
ArFrame_getUpdatedTrackables(arcore_session_.get(), arcore_frame_.get(),
plane_tracked_type, arcore_planes_.get());
ForEachArCorePlane([this, &result](ArPlane* ar_plane) {
ForEachArCorePlane([this, &result](
internal::ScopedArCoreObject<ArTrackable*> trackable,
ArPlane* ar_plane) {
// orientation
ArPlaneType plane_type;
ArPlane_getType(arcore_session_.get(), ar_plane, &plane_type);
......@@ -426,7 +462,13 @@ std::vector<int32_t> ArCoreImpl::GetAllPlaneIds() {
ArSession_getAllTrackables(arcore_session_.get(), plane_tracked_type,
arcore_planes_.get());
ForEachArCorePlane([this, &result](ArPlane* ar_plane) {
std::unordered_map<int32_t,
device::internal::ScopedArCoreObject<ArTrackable*>>
plane_id_to_plane_object;
ForEachArCorePlane([this, &plane_id_to_plane_object, &result](
internal::ScopedArCoreObject<ArTrackable*> trackable,
ArPlane* ar_plane) {
// ID
auto maybe_plane_id_and_created = CreateOrGetPlaneId(ar_plane);
if (!maybe_plane_id_and_created) {
......@@ -443,8 +485,11 @@ std::vector<int32_t> ArCoreImpl::GetAllPlaneIds() {
<< "Newly detected planes should be handled by GetUpdatedPlanesData().";
result.emplace_back(plane_id);
plane_id_to_plane_object[plane_id] = std::move(trackable);
});
plane_id_to_plane_object_.swap(plane_id_to_plane_object);
return result;
}
......@@ -672,6 +717,81 @@ bool ArCoreImpl::RequestHitTest(
return true;
}
base::Optional<int32_t> ArCoreImpl::CreateAnchor(
const device::mojom::VRPosePtr& pose) {
DCHECK(pose);
auto ar_pose = GetArPoseFromMojomPose(arcore_session_.get(), pose);
device::internal::ScopedArCoreObject<ArAnchor*> ar_anchor;
ArSession_acquireNewAnchor(
arcore_session_.get(), ar_pose.get(),
device::internal::ScopedArCoreObject<ArAnchor*>::Receiver(ar_anchor)
.get());
auto maybe_anchor_id_and_created = CreateOrGetAnchorId(ar_anchor.get());
if (!maybe_anchor_id_and_created) {
return base::nullopt;
}
int32_t anchor_id;
bool created;
std::tie(anchor_id, created) = *maybe_anchor_id_and_created;
DCHECK(created) << "This should always be a new anchor, not something we've "
"seen previously.";
anchor_id_to_anchor_object_[anchor_id] = std::move(ar_anchor);
return anchor_id;
}
base::Optional<int32_t> ArCoreImpl::CreateAnchor(
const device::mojom::VRPosePtr& pose,
int32_t plane_id) {
DCHECK(pose);
auto ar_pose = GetArPoseFromMojomPose(arcore_session_.get(), pose);
auto it = plane_id_to_plane_object_.find(plane_id);
if (it == plane_id_to_plane_object_.end()) {
return base::nullopt;
}
device::internal::ScopedArCoreObject<ArAnchor*> ar_anchor;
ArTrackable_acquireNewAnchor(
arcore_session_.get(), it->second.get(), ar_pose.get(),
device::internal::ScopedArCoreObject<ArAnchor*>::Receiver(ar_anchor)
.get());
auto maybe_anchor_id_and_created = CreateOrGetAnchorId(ar_anchor.get());
if (!maybe_anchor_id_and_created) {
return base::nullopt;
}
int32_t anchor_id;
bool created;
std::tie(anchor_id, created) = *maybe_anchor_id_and_created;
DCHECK(created) << "This should always be a new anchor, not something we've "
"seen previously.";
anchor_id_to_anchor_object_[anchor_id] = std::move(ar_anchor);
return anchor_id;
}
void ArCoreImpl::DetachAnchor(int32_t anchor_id) {
auto it = anchor_id_to_anchor_object_.find(anchor_id);
if (it == anchor_id_to_anchor_object_.end()) {
return;
}
ArAnchor_detach(arcore_session_.get(), it->second.get());
anchor_id_to_anchor_object_.erase(it);
}
bool ArCoreImpl::IsOnGlThread() {
return gl_thread_task_runner_->BelongsToCurrentThread();
}
......
......@@ -55,6 +55,11 @@ void inline ScopedGenericArObject<ArPlane*>::Free(ArPlane* ar_plane) {
ArTrackable_release(ArAsTrackable(ar_plane));
}
template <>
void inline ScopedGenericArObject<ArAnchor*>::Free(ArAnchor* ar_anchor) {
ArAnchor_release(ar_anchor);
}
template <>
void inline ScopedGenericArObject<ArTrackableList*>::Free(
ArTrackableList* ar_trackable_list) {
......@@ -109,6 +114,13 @@ class ArCoreImpl : public ArCore {
bool RequestHitTest(const mojom::XRRayPtr& ray,
std::vector<mojom::XRHitResultPtr>* hit_results) override;
base::Optional<int32_t> CreateAnchor(
const device::mojom::VRPosePtr& pose) override;
base::Optional<int32_t> CreateAnchor(const device::mojom::VRPosePtr& pose,
int32_t plane_id) override;
void DetachAnchor(int32_t anchor_id) override;
private:
bool IsOnGlThread();
base::WeakPtr<ArCoreImpl> GetWeakPtr() {
......@@ -162,7 +174,12 @@ class ArCoreImpl : public ArCore {
int32_t next_id_ = 1;
std::unordered_map<void*, int32_t> ar_plane_address_to_id_;
std::unordered_map<int32_t,
device::internal::ScopedArCoreObject<ArTrackable*>>
plane_id_to_plane_object_;
std::unordered_map<void*, int32_t> ar_anchor_address_to_id_;
std::unordered_map<int32_t, device::internal::ScopedArCoreObject<ArAnchor*>>
anchor_id_to_anchor_object_;
// Returns tuple containing plane id and a boolean signifying that the plane
// was created. The result will be a nullopt in case the ID should be assigned
......
......@@ -64,6 +64,7 @@ namespace {
CALL(ArSession_setCameraTextureName) \
CALL(ArSession_setDisplayGeometry) \
CALL(ArSession_update) \
CALL(ArTrackable_acquireNewAnchor) \
CALL(ArTrackable_getTrackingState) \
CALL(ArTrackable_getType) \
CALL(ArTrackable_release) \
......@@ -276,6 +277,14 @@ void ArHitResult_acquireTrackable(const ArSession* session,
out_trackable);
}
ArStatus ArTrackable_acquireNewAnchor(ArSession* session,
ArTrackable* trackable,
ArPose* pose,
ArAnchor** out_anchor) {
return arcore_api->impl_ArTrackable_acquireNewAnchor(session, trackable, pose,
out_anchor);
}
void ArTrackable_getTrackingState(const ArSession* session,
const ArTrackable* trackable,
ArTrackingState* out_tracking_state) {
......
......@@ -231,15 +231,52 @@ mojom::XRPlaneDetectionDataPtr FakeArCore::GetDetectedPlanesData() {
mojom::XRAnchorsDataPtr FakeArCore::GetAnchorsData() {
std::vector<mojom::XRAnchorDataPtr> result;
std::vector<int32_t> result_ids;
// 2m ahead of the origin, neutral orientation facing forward.
mojom::VRPosePtr pose = mojom::VRPose::New();
pose->position = gfx::Point3F(0.0, 0.0, -2.0);
pose->orientation = gfx::Quaternion();
for (auto& anchor_id_and_data : anchors_) {
mojom::VRPosePtr pose = mojom::VRPose::New();
pose->position = anchor_id_and_data.second.position;
pose->orientation = anchor_id_and_data.second.orientation;
result.push_back(
mojom::XRAnchorData::New(anchor_id_and_data.first, std::move(pose)));
result_ids.push_back(anchor_id_and_data.first);
}
return mojom::XRAnchorsData::New(std::move(result_ids), std::move(result));
}
base::Optional<int32_t> FakeArCore::CreateAnchor(const mojom::VRPosePtr& pose,
int32_t plane_id) {
// TODO(992035): Fix this when implementing tests.
return CreateAnchor(pose);
}
base::Optional<int32_t> FakeArCore::CreateAnchor(const mojom::VRPosePtr& pose) {
DCHECK(pose);
gfx::Point3F position =
pose->position ? gfx::Point3F(pose->position->x(), pose->position->y(),
pose->position->z())
: gfx::Point3F();
gfx::Quaternion orientation =
pose->orientation
? gfx::Quaternion(pose->orientation->x(), pose->orientation->y(),
pose->orientation->z(), pose->orientation->w())
: gfx::Quaternion(0, 0, 0, 1);
result.push_back(mojom::XRAnchorData::New(2, std::move(pose)));
anchors_[next_id_] = {position, orientation};
int32_t anchor_id = next_id_;
next_id_++;
return anchor_id;
}
return mojom::XRAnchorsData::New(std::vector<int32_t>{2}, std::move(result));
void FakeArCore::DetachAnchor(int32_t anchor_id) {
auto count = anchors_.erase(anchor_id);
DCHECK_EQ(1u, count);
}
void FakeArCore::Pause() {
......
......@@ -40,6 +40,12 @@ class FakeArCore : public ArCore {
mojom::XRPlaneDetectionDataPtr GetDetectedPlanesData() override;
mojom::XRAnchorsDataPtr GetAnchorsData() override;
base::Optional<int32_t> CreateAnchor(
const device::mojom::VRPosePtr& pose) override;
base::Optional<int32_t> CreateAnchor(const device::mojom::VRPosePtr& pose,
int32_t plane_id) override;
void DetachAnchor(int32_t anchor_id) override;
void SetCameraAspect(float aspect) { camera_aspect_ = aspect; }
private:
......@@ -52,6 +58,14 @@ class FakeArCore : public ArCore {
display::Display::Rotation::ROTATE_0;
gfx::Size frame_size_;
struct FakeAnchorData {
gfx::Point3F position;
gfx::Quaternion orientation;
};
int32_t next_id_ = 100;
std::unordered_map<int32_t, FakeAnchorData> anchors_;
DISALLOW_COPY_AND_ASSIGN(FakeArCore);
};
......
......@@ -454,9 +454,17 @@ interface VRServiceClient {
OnDeviceChanged();
};
enum CreateAnchorResult {
SUCCESS = 0,
FAILURE = 1,
};
// Provides functionality for integrating environment information into an
// XRSession. For example, some AR sessions would implement hit test to allow
// developers to get the information about the world that its sensors supply.
// On XRSession end, the message pipe will be destroyed - we need to clean up
// all outstanding JavaScript promises at that time. The XRsession might end for
// example due to a call to XRSession::end() method (exposed to JavaScript).
interface XREnvironmentIntegrationProvider {
// Performs a raycast into the scene and returns a list of XRHitResults sorted
// from closest to furthest hit from the ray. Each hit result contains a
......@@ -465,6 +473,27 @@ interface XREnvironmentIntegrationProvider {
// An empty result list means there were no hits. If a nullopt is returned,
// there was an error.
RequestHitTest(XRRay ray) => (array<XRHitResult>? results);
// Issues a request to create an anchor attached to a session.
// |result| will contain status code of the request. |anchor_id| will be valid
// only if the |result| is SUCCESS.
CreateAnchor(VRPose anchor_pose) => (CreateAnchorResult result,
int32 anchor_id);
// TODO(https://crbug.com/657632): Switch anchor_id to nullable integer once
// that's available. This will allow us to remove CreateAnchorResult if we're
// not interested in obtaining detailed error information from the device.
// Issues a request to create an anchor attached to a plane.
// |result| will contain status code of the request. |anchor_id| will be valid
// only if the |result| is SUCCESS.
CreatePlaneAnchor(VRPose anchor_pose, int32 plane_id) =>
(CreateAnchorResult result, int32 anchor_id);
// TODO(https://crbug.com/657632): Ditto - make anchor_id a nullable integer..
// Detaches an existing anchor. The |anchor_id| must be a valid id of an
// anchor created by one of the CreateAnchor calls, otherwise the call will be
// ignored.
DetachAnchor(int32 anchor_id);
};
// Provides a mechanism for a channel to plumb up any button click events
......
......@@ -79,6 +79,8 @@ class XR final : public EventTargetWithInlineData,
int64_t GetSourceId() const { return ukm_source_id_; }
using EnvironmentProviderErrorCallback = base::OnceCallback<void()>;
// Registers a callback that'll be invoked when mojo invokes a disconnect
// handler on the underlying XREnvironmentIntegrationProvider remote.
void AddEnvironmentProviderErrorHandler(
EnvironmentProviderErrorCallback callback);
......
......@@ -68,8 +68,7 @@ double XRAnchor::lastChangedTime(bool& is_null) const {
}
void XRAnchor::detach() {
// TODO(992033): Actually detach anchor once anchor creation is implemented.
DVLOG(2) << "Detaching anchor, id_=" << id_;
session_->xr()->xrEnvironmentProviderPtr()->DetachAnchor(id_);
}
void XRAnchor::Trace(blink::Visitor* visitor) {
......
......@@ -376,12 +376,12 @@ void XRFrameProvider::ProcessScheduledFrame(
immersive_session_->UpdateStageParameters(frame_data->stage_parameters);
}
if (frame_data) {
immersive_session_->OnFrame(high_res_now_ms, std::move(pose_matrix),
buffer_mailbox_holder_,
frame_data->detected_planes_data);
immersive_session_->OnFrame(
high_res_now_ms, std::move(pose_matrix), buffer_mailbox_holder_,
frame_data->detected_planes_data, frame_data->anchors_data);
} else {
immersive_session_->OnFrame(high_res_now_ms, std::move(pose_matrix),
buffer_mailbox_holder_, nullptr);
buffer_mailbox_holder_, nullptr, nullptr);
}
} else {
// In the process of fulfilling the frame requests for each session they are
......@@ -425,10 +425,11 @@ void XRFrameProvider::ProcessScheduledFrame(
getPoseMatrix(frame_pose_);
if (frame_data) {
session->OnFrame(high_res_now_ms, std::move(pose_matrix), base::nullopt,
frame_data->detected_planes_data);
frame_data->detected_planes_data,
frame_data->anchors_data);
} else {
session->OnFrame(high_res_now_ms, std::move(pose_matrix), base::nullopt,
nullptr);
nullptr, nullptr);
}
}
......
......@@ -83,14 +83,10 @@ HeapVector<Member<DOMPointReadOnly>> XRPlane::polygon() const {
ScriptPromise XRPlane::createAnchor(ScriptState* script_state,
XRRigidTransform* initial_pose,
XRSpace* space) {
// TODO(https://crbug.com/992033): Implement anchor creation from a plane
// instead of rejecting the promise. This'll cause the string literal used
// below to be removed.
return ScriptPromise::RejectWithDOMException(
script_state,
MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError,
"Device does not support anchors!"));
XRSpace* space,
ExceptionState& exception_state) {
return session_->CreateAnchor(script_state, initial_pose, space, this,
exception_state);
}
void XRPlane::Update(const device::mojom::blink::XRPlaneDataPtr& plane_data,
......
......@@ -16,6 +16,7 @@
namespace blink {
class ExceptionState;
class XRRigidTransform;
class XRSession;
class XRSpace;
......@@ -49,7 +50,8 @@ class XRPlane : public ScriptWrappable {
ScriptPromise createAnchor(ScriptState* script_state,
XRRigidTransform* initial_pose,
XRSpace* space);
XRSpace* space,
ExceptionState& exception_state);
// Updates plane data from passed in |plane_data|. The resulting instance
// should be equivalent to the instance that would be create by calling
......
......@@ -20,5 +20,5 @@ interface XRPlane {
readonly attribute XRPlaneOrientation? orientation;
readonly attribute DOMHighResTimeStamp lastChangedTime;
[RuntimeEnabled=WebXRAnchors, CallWith=ScriptState] Promise<XRAnchor> createAnchor(XRRigidTransform initial_pose, XRSpace space);
[RuntimeEnabled=WebXRAnchors, CallWith=ScriptState, RaisesException] Promise<XRAnchor> createAnchor(XRRigidTransform initial_pose, XRSpace space);
};
......@@ -33,9 +33,11 @@ class ResizeObserver;
class ScriptPromiseResolver;
class V8XRFrameRequestCallback;
class XR;
class XRAnchor;
class XRAnchorSet;
class XRCanvasInputProvider;
class XRHitTestOptionsInit;
class XRPlane;
class XRRay;
class XRReferenceSpace;
class XRRenderState;
......@@ -81,7 +83,7 @@ class XRSession final
XRRenderState* renderState() const { return render_state_; }
XRWorldTrackingState* worldTrackingState() { return world_tracking_state_; }
XRSpace* viewerSpace() const;
XRAnchorSet* trackedAnchors() const { return nullptr; }
XRAnchorSet* trackedAnchors() const;
bool immersive() const;
......@@ -101,10 +103,18 @@ class XRSession final
const String& type,
ExceptionState&);
// IDL-exposed
ScriptPromise createAnchor(ScriptState* script_state,
XRRigidTransform* initial_pose,
XRSpace* space,
ExceptionState&);
ExceptionState& exception_state);
// helper, not IDL-exposed
ScriptPromise CreateAnchor(ScriptState* script_state,
XRRigidTransform* pose,
XRSpace* space,
XRPlane* plane,
ExceptionState& exception_state);
int requestAnimationFrame(V8XRFrameRequestCallback* callback);
void cancelAnimationFrame(int id);
......@@ -149,11 +159,12 @@ class XRSession final
const AtomicString& InterfaceName() const override;
void OnFocusChanged();
void OnFrame(double timestamp,
std::unique_ptr<TransformationMatrix> base_pose_matrix,
const base::Optional<gpu::MailboxHolder>& output_mailbox_holder,
const device::mojom::blink::XRPlaneDetectionDataPtr&
detected_planes_data);
void OnFrame(
double timestamp,
std::unique_ptr<TransformationMatrix> base_pose_matrix,
const base::Optional<gpu::MailboxHolder>& output_mailbox_holder,
const device::mojom::blink::XRPlaneDetectionDataPtr& detected_planes_data,
const device::mojom::blink::XRAnchorsDataPtr& tracked_anchors_data);
void OnInputStateChange(
int16_t frame_id,
......@@ -241,9 +252,17 @@ class XRSession final
base::Optional<WTF::Vector<device::mojom::blink::XRHitResultPtr>>
results);
void OnCreateAnchorResult(ScriptPromiseResolver* resolver,
device::mojom::CreateAnchorResult result,
int32_t id);
void EnsureEnvironmentErrorHandler();
void OnEnvironmentProviderError();
void ProcessAnchorsData(
const device::mojom::blink::XRAnchorsDataPtr& tracked_anchors_data,
double timestamp);
const Member<XR> xr_;
const SessionMode mode_;
const bool environment_integration_;
......@@ -255,6 +274,10 @@ class XRSession final
HeapVector<Member<XRRenderStateInit>> pending_render_state_;
XRSessionFeatureSet enabled_features_;
bool is_tracked_anchors_null_ = true;
HeapHashMap<int32_t, Member<XRAnchor>> anchor_ids_to_anchors_;
WTF::Vector<XRViewData> views_;
Member<XRInputSourceArray> input_sources_;
......@@ -262,6 +285,8 @@ class XRSession final
Member<XRCanvasInputProvider> canvas_input_provider_;
bool environment_error_handler_subscribed_ = false;
HeapHashSet<Member<ScriptPromiseResolver>> hit_test_promises_;
// Set of promises returned from CreateAnchor that are still in-flight.
HeapHashSet<Member<ScriptPromiseResolver>> create_anchor_promises_;
HeapVector<Member<XRReferenceSpace>> reference_spaces_;
bool has_xr_focus_ = true;
......
......@@ -28,7 +28,9 @@ class XRSpace : public EventTargetWithInlineData {
explicit XRSpace(XRSession*);
~XRSpace() override;
// Get a transform that maps from this space to mojo space.
// Get a transform that maps from this space to mojo space (aka device space).
// Unless noted otherwise, all data returned over vr_service.mojom interfaces
// is relative to mojo space.
// Returns nullptr if computing a transform is not possible.
virtual std::unique_ptr<TransformationMatrix> GetTransformToMojoSpace();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment