Commit 8be89ae0 authored by Jacob DeWitt's avatar Jacob DeWitt Committed by Commit Bot

Update emulated position on each XRFrame

For both the head poses and input poses, send this value through mojo
from the device process to the renderer process on every frame.

Bug: 969131
Change-Id: Ie895deb75bddb6dd883d09828cfcb30f335d3793
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1825478
Auto-Submit: Jacob DeWitt <jacde@chromium.org>
Commit-Queue: Will Harris <wfh@chromium.org>
Reviewed-by: default avatarWill Harris <wfh@chromium.org>
Reviewed-by: default avatarKlaus Weidner <klausw@chromium.org>
Reviewed-by: default avatarAlexander Cooper <alcooper@chromium.org>
Cr-Commit-Position: refs/heads/master@{#701389}
parent 17627185
...@@ -707,7 +707,7 @@ mojom::XRInputSourceStatePtr ArCoreGl::GetInputSourceState() { ...@@ -707,7 +707,7 @@ mojom::XRInputSourceStatePtr ArCoreGl::GetInputSourceState() {
state->description->target_ray_mode = device::mojom::XRTargetRayMode::TAPPING; state->description->target_ray_mode = device::mojom::XRTargetRayMode::TAPPING;
// Controller doesn't have a measured position. // Controller doesn't have a measured position.
state->description->emulated_position = true; state->emulated_position = true;
// The Renderer code ignores state->grip for TAPPING (screen-based) target ray // The Renderer code ignores state->grip for TAPPING (screen-based) target ray
// mode, so we don't bother filling it in here. If this does get used at // mode, so we don't bother filling it in here. If this does get used at
......
...@@ -63,7 +63,7 @@ CardboardInputDelegate::GetInputSourceState() { ...@@ -63,7 +63,7 @@ CardboardInputDelegate::GetInputSourceState() {
// It's a gaze-cursor-based device. // It's a gaze-cursor-based device.
state->description->target_ray_mode = device::mojom::XRTargetRayMode::GAZING; state->description->target_ray_mode = device::mojom::XRTargetRayMode::GAZING;
state->description->emulated_position = true; state->emulated_position = true;
// No implicit handedness // No implicit handedness
state->description->handedness = device::mojom::XRHandedness::NONE; state->description->handedness = device::mojom::XRHandedness::NONE;
......
...@@ -158,7 +158,7 @@ device::mojom::XRInputSourceStatePtr GvrInputDelegate::GetInputSourceState() { ...@@ -158,7 +158,7 @@ device::mojom::XRInputSourceStatePtr GvrInputDelegate::GetInputSourceState() {
device::mojom::XRTargetRayMode::POINTING; device::mojom::XRTargetRayMode::POINTING;
// Controller uses an arm model. // Controller uses an arm model.
state->description->emulated_position = true; state->emulated_position = true;
if (controller_->IsConnected()) { if (controller_->IsConnected()) {
// Set the primary button state. // Set the primary button state.
......
...@@ -165,7 +165,7 @@ InputDelegateForTesting::GetInputSourceState() { ...@@ -165,7 +165,7 @@ InputDelegateForTesting::GetInputSourceState() {
state->source_id = 1; state->source_id = 1;
state->description->target_ray_mode = state->description->target_ray_mode =
device::mojom::XRTargetRayMode::POINTING; device::mojom::XRTargetRayMode::POINTING;
state->description->emulated_position = true; state->emulated_position = true;
return state; return state;
} }
......
...@@ -347,8 +347,8 @@ device::mojom::XRInputSourceStatePtr OculusRenderLoop::GetTouchData( ...@@ -347,8 +347,8 @@ device::mojom::XRInputSourceStatePtr OculusRenderLoop::GetTouchData(
break; break;
} }
// Touch controller are fully 6DoF. // Touch controllers are fully 6DoF.
desc->emulated_position = false; state->emulated_position = false;
// The grip pose will be rotated and translated back a bit from the pointer // The grip pose will be rotated and translated back a bit from the pointer
// pose, which is what the Oculus API returns. // pose, which is what the Oculus API returns.
......
...@@ -290,6 +290,9 @@ std::vector<mojom::XRInputSourceStatePtr> OpenVRRenderLoop::GetInputState( ...@@ -290,6 +290,9 @@ std::vector<mojom::XRInputSourceStatePtr> OpenVRRenderLoop::GetInputState(
controller_state, handedness); controller_state, handedness);
state->gamepad = input_source_data.gamepad; state->gamepad = input_source_data.gamepad;
// OpenVR controller are fully 6DoF.
state->emulated_position = false;
// Re-send the controller's description if it's newly active or if the // Re-send the controller's description if it's newly active or if the
// handedness or profile strings have changed. // handedness or profile strings have changed.
if (newly_active || if (newly_active ||
...@@ -304,9 +307,6 @@ std::vector<mojom::XRInputSourceStatePtr> OpenVRRenderLoop::GetInputState( ...@@ -304,9 +307,6 @@ std::vector<mojom::XRInputSourceStatePtr> OpenVRRenderLoop::GetInputState(
desc->handedness = handedness; desc->handedness = handedness;
input_active_state.controller_role = controller_role; input_active_state.controller_role = controller_role;
// OpenVR controller are fully 6DoF.
desc->emulated_position = false;
// Tweak the pointer transform so that it's angled down from the // Tweak the pointer transform so that it's angled down from the
// grip. This should be a bit more ergonomic. // grip. This should be a bit more ergonomic.
desc->pointer_offset = gfx::Transform(); desc->pointer_offset = gfx::Transform();
......
...@@ -115,7 +115,6 @@ struct XRPresentationConnection { ...@@ -115,7 +115,6 @@ struct XRPresentationConnection {
struct XRInputSourceDescription { struct XRInputSourceDescription {
XRTargetRayMode target_ray_mode; XRTargetRayMode target_ray_mode;
XRHandedness handedness; XRHandedness handedness;
bool emulated_position;
// Transform from the grip matrix to the pointer's origin and orientation. // Transform from the grip matrix to the pointer's origin and orientation.
gfx.mojom.Transform? pointer_offset; gfx.mojom.Transform? pointer_offset;
...@@ -137,6 +136,10 @@ struct XRInputSourceState { ...@@ -137,6 +136,10 @@ struct XRInputSourceState {
// Transform to the controllers grip (users palm) from start space origin. // Transform to the controllers grip (users palm) from start space origin.
gfx.mojom.Transform? grip; gfx.mojom.Transform? grip;
// True when position is estimated by something like a neck or arm model.
// False when position is based on sensors tracking a 6DoF pose.
bool emulated_position;
// Describes the current state of the primary input. // Describes the current state of the primary input.
bool primary_input_pressed; bool primary_input_pressed;
...@@ -174,6 +177,10 @@ struct VRPose { ...@@ -174,6 +177,10 @@ struct VRPose {
gfx.mojom.Quaternion? orientation; gfx.mojom.Quaternion? orientation;
gfx.mojom.Point3F? position; gfx.mojom.Point3F? position;
// True when position is estimated by something like a neck or arm model.
// False when position is based on sensors tracking a 6DoF pose.
bool emulated_position;
// Velocity/Acceleration is in global coordinates, as rad/s. // Velocity/Acceleration is in global coordinates, as rad/s.
gfx.mojom.Vector3dF? angular_velocity; gfx.mojom.Vector3dF? angular_velocity;
gfx.mojom.Vector3dF? linear_velocity; gfx.mojom.Vector3dF? linear_velocity;
......
...@@ -553,7 +553,7 @@ ParsedInputState MixedRealityInputHelper::ParseWindowsSourceState( ...@@ -553,7 +553,7 @@ ParsedInputState MixedRealityInputHelper::ParseWindowsSourceState(
device::mojom::XRInputSourceDescription::New(); device::mojom::XRInputSourceDescription::New();
// If we've gotten this far we've gotten the real position. // If we've gotten this far we've gotten the real position.
description->emulated_position = false; source_state->emulated_position = false;
description->pointer_offset = grip_from_pointer; description->pointer_offset = grip_from_pointer;
if (is_voice) { if (is_voice) {
......
...@@ -833,8 +833,6 @@ mojom::XRFrameDataPtr MixedRealityRenderLoop::GetNextFrameData() { ...@@ -833,8 +833,6 @@ mojom::XRFrameDataPtr MixedRealityRenderLoop::GetNextFrameData() {
if (anchor_origin_ && if (anchor_origin_ &&
pose_->TryGetViewTransform(anchor_origin_.get(), &view)) { pose_->TryGetViewTransform(anchor_origin_.get(), &view)) {
got_view = true; got_view = true;
// TODO(http://crbug.com/931393): Send down emulated_position_, and report
// reset events when this changes.
emulated_position_ = false; emulated_position_ = false;
ABI::Windows::Foundation::Numerics::Matrix4x4 origin_from_attached; ABI::Windows::Foundation::Numerics::Matrix4x4 origin_from_attached;
if (attached_coordinates->TryGetTransformTo(anchor_origin_.get(), if (attached_coordinates->TryGetTransformTo(anchor_origin_.get(),
...@@ -910,6 +908,8 @@ mojom::XRFrameDataPtr MixedRealityRenderLoop::GetNextFrameData() { ...@@ -910,6 +908,8 @@ mojom::XRFrameDataPtr MixedRealityRenderLoop::GetNextFrameData() {
ret->pose->input_state = ret->pose->input_state =
input_helper_->GetInputState(anchor_origin_.get(), timestamp_.get()); input_helper_->GetInputState(anchor_origin_.get(), timestamp_.get());
ret->pose->emulated_position = emulated_position_;
if (emulated_position_ && last_origin_from_attached_) { if (emulated_position_ && last_origin_from_attached_) {
gfx::DecomposedTransform attached_from_view_decomp; gfx::DecomposedTransform attached_from_view_decomp;
attached_from_view_decomp.quaternion = (*ret->pose->orientation); attached_from_view_decomp.quaternion = (*ret->pose->orientation);
......
...@@ -106,8 +106,10 @@ XRPose* XRFrame::getPose(XRSpace* space_A, ...@@ -106,8 +106,10 @@ XRPose* XRFrame::getPose(XRSpace* space_A,
return space_A->getPose(space_B, mojo_from_viewer_.get()); return space_A->getPose(space_B, mojo_from_viewer_.get());
} }
void XRFrame::SetMojoFromViewer(const TransformationMatrix& mojo_from_viewer) { void XRFrame::SetMojoFromViewer(const TransformationMatrix& mojo_from_viewer,
bool emulated_position) {
mojo_from_viewer_ = std::make_unique<TransformationMatrix>(mojo_from_viewer); mojo_from_viewer_ = std::make_unique<TransformationMatrix>(mojo_from_viewer);
emulated_position_ = emulated_position;
} }
void XRFrame::Deactivate() { void XRFrame::Deactivate() {
......
...@@ -41,7 +41,7 @@ class XRFrame final : public ScriptWrappable { ...@@ -41,7 +41,7 @@ class XRFrame final : public ScriptWrappable {
XRWorldInformation* worldInformation() const { return world_information_; } XRWorldInformation* worldInformation() const { return world_information_; }
XRAnchorSet* trackedAnchors() const; XRAnchorSet* trackedAnchors() const;
void SetMojoFromViewer(const TransformationMatrix&); void SetMojoFromViewer(const TransformationMatrix&, bool emulated_position);
void Trace(blink::Visitor*) override; void Trace(blink::Visitor*) override;
...@@ -55,6 +55,8 @@ class XRFrame final : public ScriptWrappable { ...@@ -55,6 +55,8 @@ class XRFrame final : public ScriptWrappable {
XRHitTestSource* hitTestSource, XRHitTestSource* hitTestSource,
XRSpace* relativeTo); XRSpace* relativeTo);
bool EmulatedPosition() const { return emulated_position_; }
private: private:
std::unique_ptr<TransformationMatrix> GetAdjustedPoseMatrix(XRSpace*) const; std::unique_ptr<TransformationMatrix> GetAdjustedPoseMatrix(XRSpace*) const;
XRPose* GetTargetRayPose(XRInputSource*, XRSpace*) const; XRPose* GetTargetRayPose(XRInputSource*, XRSpace*) const;
...@@ -76,6 +78,8 @@ class XRFrame final : public ScriptWrappable { ...@@ -76,6 +78,8 @@ class XRFrame final : public ScriptWrappable {
// animation frames. getViewerPose should only be called from JS on active // animation frames. getViewerPose should only be called from JS on active
// animation frames. // animation frames.
bool is_animation_frame_ = false; bool is_animation_frame_ = false;
bool emulated_position_ = false;
}; };
} // namespace blink } // namespace blink
......
...@@ -254,6 +254,10 @@ void XRFrameProvider::OnImmersiveFrameData( ...@@ -254,6 +254,10 @@ void XRFrameProvider::OnImmersiveFrameData(
frame_id_ = data->frame_id; frame_id_ = data->frame_id;
buffer_mailbox_holder_ = data->buffer_holder; buffer_mailbox_holder_ = data->buffer_holder;
if (frame_pose_) {
emulated_position_ = frame_pose_->emulated_position;
}
pending_immersive_vsync_ = false; pending_immersive_vsync_ = false;
// Post a task to handle scheduled animations after the current // Post a task to handle scheduled animations after the current
...@@ -336,7 +340,8 @@ void XRFrameProvider::ProcessScheduledFrame( ...@@ -336,7 +340,8 @@ void XRFrameProvider::ProcessScheduledFrame(
// presentation frame as newly created presentation frame will get passed to // presentation frame as newly created presentation frame will get passed to
// the input source select[/start/end] events. // the input source select[/start/end] events.
immersive_session_->UpdatePresentationFrameState( immersive_session_->UpdatePresentationFrameState(
high_res_now_ms, getPoseMatrix(frame_pose_), frame_data); high_res_now_ms, getPoseMatrix(frame_pose_), frame_data,
emulated_position_);
if (frame_pose_) { if (frame_pose_) {
base::span<const device::mojom::blink::XRInputSourceStatePtr> base::span<const device::mojom::blink::XRInputSourceStatePtr>
...@@ -401,8 +406,9 @@ void XRFrameProvider::ProcessScheduledFrame( ...@@ -401,8 +406,9 @@ void XRFrameProvider::ProcessScheduledFrame(
// Prior to updating input source state, update the state needed to create // Prior to updating input source state, update the state needed to create
// presentation frame as newly created presentation frame will get passed // presentation frame as newly created presentation frame will get passed
// to the input source select[/start/end] events. // to the input source select[/start/end] events.
session->UpdatePresentationFrameState( session->UpdatePresentationFrameState(high_res_now_ms,
high_res_now_ms, getPoseMatrix(frame_pose_), frame_data); getPoseMatrix(frame_pose_),
frame_data, emulated_position_);
if (frame_pose_) { if (frame_pose_) {
base::span<const device::mojom::blink::XRInputSourceStatePtr> base::span<const device::mojom::blink::XRInputSourceStatePtr>
......
...@@ -85,6 +85,8 @@ class XRFrameProvider final : public GarbageCollected<XRFrameProvider> { ...@@ -85,6 +85,8 @@ class XRFrameProvider final : public GarbageCollected<XRFrameProvider> {
base::Optional<gpu::MailboxHolder> buffer_mailbox_holder_; base::Optional<gpu::MailboxHolder> buffer_mailbox_holder_;
bool last_has_focus_ = false; bool last_has_focus_ = false;
bool emulated_position_ = false;
}; };
} // namespace blink } // namespace blink
......
...@@ -79,7 +79,6 @@ XRInputSource* XRInputSource::CreateOrUpdateFrom( ...@@ -79,7 +79,6 @@ XRInputSource* XRInputSource::CreateOrUpdateFrom(
updated_source->state_.target_ray_mode = desc->target_ray_mode; updated_source->state_.target_ray_mode = desc->target_ray_mode;
updated_source->state_.handedness = desc->handedness; updated_source->state_.handedness = desc->handedness;
updated_source->state_.emulated_position = desc->emulated_position;
updated_source->input_from_pointer_ = updated_source->input_from_pointer_ =
TryGetTransformationMatrix(desc->pointer_offset); TryGetTransformationMatrix(desc->pointer_offset);
...@@ -92,6 +91,8 @@ XRInputSource* XRInputSource::CreateOrUpdateFrom( ...@@ -92,6 +91,8 @@ XRInputSource* XRInputSource::CreateOrUpdateFrom(
updated_source->mojo_from_input_ = TryGetTransformationMatrix(state->grip); updated_source->mojo_from_input_ = TryGetTransformationMatrix(state->grip);
updated_source->state_.emulated_position = state->emulated_position;
return updated_source; return updated_source;
} }
......
...@@ -924,7 +924,8 @@ void XRSession::ApplyPendingRenderState() { ...@@ -924,7 +924,8 @@ void XRSession::ApplyPendingRenderState() {
void XRSession::UpdatePresentationFrameState( void XRSession::UpdatePresentationFrameState(
double timestamp, double timestamp,
std::unique_ptr<TransformationMatrix> mojo_from_viewer, std::unique_ptr<TransformationMatrix> mojo_from_viewer,
const device::mojom::blink::XRFrameDataPtr& frame_data) { const device::mojom::blink::XRFrameDataPtr& frame_data,
bool emulated_position) {
TRACE_EVENT0("gpu", __FUNCTION__); TRACE_EVENT0("gpu", __FUNCTION__);
DVLOG(2) << __FUNCTION__ << " : frame_data valid? " DVLOG(2) << __FUNCTION__ << " : frame_data valid? "
<< (frame_data ? true : false); << (frame_data ? true : false);
...@@ -936,6 +937,8 @@ void XRSession::UpdatePresentationFrameState( ...@@ -936,6 +937,8 @@ void XRSession::UpdatePresentationFrameState(
DVLOG(2) << __FUNCTION__ << " : mojo_from_viewer_ valid? " DVLOG(2) << __FUNCTION__ << " : mojo_from_viewer_ valid? "
<< (mojo_from_viewer_ ? true : false); << (mojo_from_viewer_ ? true : false);
emulated_position_ = emulated_position;
// Update objects that might change on per-frame basis. // Update objects that might change on per-frame basis.
if (frame_data) { if (frame_data) {
world_information_->ProcessPlaneInformation( world_information_->ProcessPlaneInformation(
...@@ -1041,7 +1044,9 @@ XRFrame* XRSession::CreatePresentationFrame() { ...@@ -1041,7 +1044,9 @@ XRFrame* XRSession::CreatePresentationFrame() {
if (mojo_from_viewer_ && visibility_state_ != XRVisibilityState::HIDDEN) { if (mojo_from_viewer_ && visibility_state_ != XRVisibilityState::HIDDEN) {
DVLOG(2) << __func__ << " : mojo_from_viewer_ is set and not hidden," DVLOG(2) << __func__ << " : mojo_from_viewer_ is set and not hidden,"
<< " updating presentation frame"; << " updating presentation frame";
presentation_frame->SetMojoFromViewer(*mojo_from_viewer_);
presentation_frame->SetMojoFromViewer(*mojo_from_viewer_,
EmulatedPosition());
} }
return presentation_frame; return presentation_frame;
} }
......
...@@ -187,15 +187,14 @@ class XRSession final ...@@ -187,15 +187,14 @@ class XRSession final
device::mojom::blink::XRInputSourceButtonListenerAssociatedPtrInfo device::mojom::blink::XRInputSourceButtonListenerAssociatedPtrInfo
GetInputClickListener(); GetInputClickListener();
// TODO(crbug.com/969131): Update the mojom to deliver this per-frame.
bool EmulatedPosition() const { bool EmulatedPosition() const {
if (display_info_) {
return !display_info_->capabilities->has_position;
}
// If we don't have display info then we should be using the identity // If we don't have display info then we should be using the identity
// reference space, which by definition will be emulating the position. // reference space, which by definition will be emulating the position.
return true; if (!display_info_) {
return true;
}
return emulated_position_;
} }
// Immersive sessions currently use two views for VR, and only a single view // Immersive sessions currently use two views for VR, and only a single view
...@@ -234,7 +233,8 @@ class XRSession final ...@@ -234,7 +233,8 @@ class XRSession final
void UpdatePresentationFrameState( void UpdatePresentationFrameState(
double timestamp, double timestamp,
std::unique_ptr<TransformationMatrix> mojo_from_viewer, std::unique_ptr<TransformationMatrix> mojo_from_viewer,
const device::mojom::blink::XRFrameDataPtr& frame_data); const device::mojom::blink::XRFrameDataPtr& frame_data,
bool emulated_position);
private: private:
class XRSessionResizeObserverDelegate; class XRSessionResizeObserverDelegate;
...@@ -340,6 +340,8 @@ class XRSession final ...@@ -340,6 +340,8 @@ class XRSession final
bool sensorless_session_ = false; bool sensorless_session_ = false;
int16_t last_frame_id_ = -1; int16_t last_frame_id_ = -1;
bool emulated_position_ = false;
}; };
} // namespace blink } // namespace blink
......
...@@ -268,6 +268,7 @@ class MockRuntime { ...@@ -268,6 +268,7 @@ class MockRuntime {
this.pose_ = { this.pose_ = {
orientation: { x: q[0], y: q[1], z: q[2], w: q[3] }, orientation: { x: q[0], y: q[1], z: q[2], w: q[3] },
position: { x: p[0], y: p[1], z: p[2] }, position: { x: p[0], y: p[1], z: p[2] },
emulatedPosition: emulatedPosition,
angularVelocity: null, angularVelocity: null,
linearVelocity: null, linearVelocity: null,
angularAcceleration: null, angularAcceleration: null,
...@@ -691,6 +692,7 @@ class MockXRInputSource { ...@@ -691,6 +692,7 @@ class MockXRInputSource {
this.desc_dirty_ = true; this.desc_dirty_ = true;
this.pointer_offset_ = new gfx.mojom.Transform(); this.pointer_offset_ = new gfx.mojom.Transform();
this.pointer_offset_.matrix = getMatrixFromTransform(transform); this.pointer_offset_.matrix = getMatrixFromTransform(transform);
this.emulated_position_ = emulatedPosition;
} }
disconnect() { disconnect() {
...@@ -812,11 +814,11 @@ class MockXRInputSource { ...@@ -812,11 +814,11 @@ class MockXRInputSource {
input_state.gamepad = this.gamepad_; input_state.gamepad = this.gamepad_;
input_state.emulatedPosition = this.emulated_position_;
if (this.desc_dirty_) { if (this.desc_dirty_) {
let input_desc = new device.mojom.XRInputSourceDescription(); let input_desc = new device.mojom.XRInputSourceDescription();
input_desc.emulatedPosition = this.emulated_position_;
switch (this.target_ray_mode_) { switch (this.target_ray_mode_) {
case 'gaze': case 'gaze':
input_desc.targetRayMode = device.mojom.XRTargetRayMode.GAZING; input_desc.targetRayMode = device.mojom.XRTargetRayMode.GAZING;
......
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="resources/webxr_util.js"></script>
<script src="resources/webxr_test_constants.js"></script>
<canvas></canvas>
<script>
let testName = "XRFrame getViewerPose has emulatedPosition set properly.";
const poseTransform = {
position: [1, 1, 1],
orientation: [0.5, 0.5, 0.5, 0.5]
};
let testFunction = function(session, fakeDeviceController, t) {
return session.requestReferenceSpace('local')
.then((referenceSpace) => new Promise((resolve, reject) => {
function CheckPositionNotEmulated(time, vrFrame){
t.step(() => {
let pose = vrFrame.getViewerPose(referenceSpace);
assert_not_equals(pose, null);
assert_equals(pose.emulatedPosition, false);
fakeDeviceController.setViewerOrigin(poseTransform, true);
});
session.requestAnimationFrame(CheckPositionEmulated);
}
function CheckPositionEmulated(time, vrFrame) {
t.step(() => {
let pose = vrFrame.getViewerPose(referenceSpace);
assert_not_equals(pose, null);
assert_equals(pose.emulatedPosition, true);
});
// Finished.
resolve();
}
session.requestAnimationFrame(CheckPositionNotEmulated);
}));
};
xr_session_promise_test(testName, testFunction,
TRACKED_IMMERSIVE_DEVICE, 'immersive-vr');
</script>
</body>
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/webxr_util.js"></script>
<script src="resources/webxr_test_constants.js"></script>
<script src="resources/webxr_test_asserts.js"></script>
<canvas id="webgl-canvas"></canvas>
<script>
let testName = "Poses from XRInputSource.gripSpace have emulatedPosition set "
+ "properly";
let fakeDeviceInitParams = TRACKED_IMMERSIVE_DEVICE;
let testFunction =
(session, fakeDeviceController, t) => new Promise((resolve) => {
let input_source = fakeDeviceController.simulateInputSourceConnection({
handedness: "right",
targetRayMode: "tracked-pointer",
pointerOrigin: IDENTITY_TRANSFORM,
gripOrigin: VALID_GRIP_TRANSFORM,
profiles: []
});
// Must have a reference space to get input poses. eye-level doesn't apply
// any transforms to the given matrix.
session.requestReferenceSpace('local').then( (referenceSpace) => {
function CheckPositionNotEmulated(time, xrFrame) {
let source = session.inputSources[0];
let grip_pose = xrFrame.getPose(source.gripSpace, referenceSpace);
t.step(() => {
assert_not_equals(grip_pose, null);
assert_equals(grip_pose.emulatedPosition, false);
});
input_source.setGripOrigin(VALID_GRIP_TRANSFORM, true);
session.requestAnimationFrame(CheckPositionEmulated);
}
function CheckPositionEmulated(time, xrFrame) {
let source = session.inputSources[0];
let grip_pose = xrFrame.getPose(source.gripSpace, referenceSpace);
t.step(() => {
assert_not_equals(grip_pose, null);
assert_equals(grip_pose.emulatedPosition, true);
});
resolve();
}
// Can only request input poses in an xr frame.
session.requestAnimationFrame(CheckPositionNotEmulated);
});
});
xr_session_promise_test(
testName, testFunction, fakeDeviceInitParams, 'immersive-vr');
</script>
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