Commit f99b1963 authored by Bill Orr's avatar Bill Orr Committed by Commit Bot

Support WMR tracking loss

Fall back to 3dof-orientation only when tracking is lost. If we
previously were tracking, use the last position.

This doesn't add emulated controller positions - controllers aren't
reported if tracking is lost.

Bug: 944605, 928814
Change-Id: Idc963f66b30905012a7fb6675c07e0d22a382d23
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1545153
Commit-Queue: Bill Orr <billorr@chromium.org>
Reviewed-by: default avatarKlaus Weidner <klausw@chromium.org>
Cr-Commit-Position: refs/heads/master@{#646625}
parent 64758a0f
...@@ -271,6 +271,8 @@ void MixedRealityRenderLoop::StopRuntime() { ...@@ -271,6 +271,8 @@ void MixedRealityRenderLoop::StopRuntime() {
holographic_space_ = nullptr; holographic_space_ = nullptr;
origin_ = nullptr; origin_ = nullptr;
stage_origin_ = nullptr; stage_origin_ = nullptr;
last_origin_from_attached_ = base::nullopt;
attached_ = nullptr;
holographic_frame_ = nullptr; holographic_frame_ = nullptr;
timestamp_ = nullptr; timestamp_ = nullptr;
...@@ -309,6 +311,12 @@ void MixedRealityRenderLoop::InitializeOrigin() { ...@@ -309,6 +311,12 @@ void MixedRealityRenderLoop::InitializeOrigin() {
if (FAILED(hr)) if (FAILED(hr))
return; return;
if (!attached_) {
hr = locator->CreateAttachedFrameOfReferenceAtCurrentHeading(&attached_);
if (FAILED(hr))
return;
}
ComPtr<ISpatialStationaryFrameOfReference> stationary_frame; ComPtr<ISpatialStationaryFrameOfReference> stationary_frame;
hr = locator->CreateStationaryFrameOfReferenceAtCurrentLocation( hr = locator->CreateStationaryFrameOfReferenceAtCurrentLocation(
&stationary_frame); &stationary_frame);
...@@ -320,9 +328,6 @@ void MixedRealityRenderLoop::InitializeOrigin() { ...@@ -320,9 +328,6 @@ void MixedRealityRenderLoop::InitializeOrigin() {
hr = stationary_frame->get_CoordinateSystem(&origin_); hr = stationary_frame->get_CoordinateSystem(&origin_);
if (FAILED(hr)) if (FAILED(hr))
return; return;
// TODO(billorr): Consider adding support for using an attached frame for
// orientation-only experiences.
} }
void MixedRealityRenderLoop::InitializeStageOrigin() { void MixedRealityRenderLoop::InitializeStageOrigin() {
...@@ -353,6 +358,8 @@ void MixedRealityRenderLoop::InitializeStageOrigin() { ...@@ -353,6 +358,8 @@ void MixedRealityRenderLoop::InitializeStageOrigin() {
void MixedRealityRenderLoop::OnSessionStart() { void MixedRealityRenderLoop::OnSessionStart() {
// Each session should start with new origins. // Each session should start with new origins.
origin_ = nullptr; origin_ = nullptr;
attached_ = nullptr;
last_origin_from_attached_ = base::nullopt;
InitializeOrigin(); InitializeOrigin();
stage_origin_ = nullptr; stage_origin_ = nullptr;
...@@ -717,7 +724,7 @@ mojom::XRFrameDataPtr MixedRealityRenderLoop::GetNextFrameData() { ...@@ -717,7 +724,7 @@ mojom::XRFrameDataPtr MixedRealityRenderLoop::GetNextFrameData() {
mojom::XRFrameDataPtr ret = mojom::XRFrameDataPtr ret =
CreateDefaultFrameData(timestamp_, next_frame_id_); CreateDefaultFrameData(timestamp_, next_frame_id_);
if (!origin_ || !pose_) { if ((!attached_ && !origin_) || !pose_) {
TRACE_EVENT_INSTANT0("xr", "No origin or no pose", TRACE_EVENT_INSTANT0("xr", "No origin or no pose",
TRACE_EVENT_SCOPE_THREAD); TRACE_EVENT_SCOPE_THREAD);
// If we don't have an origin or pose for this frame, we can still give out // If we don't have an origin or pose for this frame, we can still give out
...@@ -725,23 +732,44 @@ mojom::XRFrameDataPtr MixedRealityRenderLoop::GetNextFrameData() { ...@@ -725,23 +732,44 @@ mojom::XRFrameDataPtr MixedRealityRenderLoop::GetNextFrameData() {
return ret; return ret;
} }
ComPtr<ISpatialCoordinateSystem> attached_coordinates;
HRESULT hr = attached_->GetStationaryCoordinateSystemAtTimestamp(
timestamp_.Get(), &attached_coordinates);
if (FAILED(hr))
return ret;
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IReference< Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IReference<
ABI::Windows::Graphics::Holographic::HolographicStereoTransform>> ABI::Windows::Graphics::Holographic::HolographicStereoTransform>>
view_ref; view_ref;
HRESULT hr = pose_->TryGetViewTransform(origin_.Get(), &view_ref); if (origin_ &&
if (FAILED(hr) || !view_ref) { SUCCEEDED(pose_->TryGetViewTransform(origin_.Get(), &view_ref)) &&
// If we can't locate origin_, throw it away and try to get a new origin view_ref) {
// next frame. // TODO(http://crbug.com/931393): Send down emulated_position_, and report
// TODO(billorr): Try to keep the origin working over multiple frames, doing // reset events when this changes.
// some transform work. emulated_position_ = false;
TRACE_EVENT_INSTANT0("xr", "Failed to locate origin", ComPtr<IReference<ABI::Windows::Foundation::Numerics::Matrix4x4>>
TRACE_EVENT_SCOPE_THREAD); attached_to_origin_ref;
origin_ = nullptr; hr = attached_coordinates->TryGetTransformTo(origin_.Get(),
&attached_to_origin_ref);
// TODO(https://crbug.com/945408): Determine whether StageOrigin should only if (SUCCEEDED(hr) && attached_to_origin_ref) {
// be nulled out when we get the changed event. ABI::Windows::Foundation::Numerics::Matrix4x4 transform;
stage_origin_ = nullptr; hr = attached_to_origin_ref->get_Value(&transform);
return ret; DCHECK(SUCCEEDED(hr));
last_origin_from_attached_ = gfx::Transform(
transform.M11, transform.M21, transform.M31, transform.M41,
transform.M12, transform.M22, transform.M32, transform.M42,
transform.M13, transform.M23, transform.M33, transform.M43,
transform.M14, transform.M24, transform.M34, transform.M44);
}
} else {
emulated_position_ = true;
if (FAILED(pose_->TryGetViewTransform(attached_coordinates.Get(),
&view_ref)) ||
!view_ref) {
TRACE_EVENT_INSTANT0("xr", "Failed to locate origin",
TRACE_EVENT_SCOPE_THREAD);
return ret;
}
} }
ABI::Windows::Graphics::Holographic::HolographicStereoTransform view; ABI::Windows::Graphics::Holographic::HolographicStereoTransform view;
...@@ -802,6 +830,33 @@ mojom::XRFrameDataPtr MixedRealityRenderLoop::GetNextFrameData() { ...@@ -802,6 +830,33 @@ mojom::XRFrameDataPtr MixedRealityRenderLoop::GetNextFrameData() {
ret->pose->input_state = input_helper_->GetInputState(origin_, timestamp_); ret->pose->input_state = input_helper_->GetInputState(origin_, timestamp_);
if (emulated_position_ && last_origin_from_attached_) {
gfx::DecomposedTransform attached_from_view_decomp;
attached_from_view_decomp.quaternion = gfx::Quaternion(
(*ret->pose->orientation)[0], (*ret->pose->orientation)[1],
(*ret->pose->orientation)[2], (*ret->pose->orientation)[3]);
for (int i = 0; i < 3; ++i) {
attached_from_view_decomp.translate[i] = (*ret->pose->position)[i];
}
gfx::Transform attached_from_view =
gfx::ComposeTransform(attached_from_view_decomp);
gfx::Transform origin_from_view =
(*last_origin_from_attached_) * attached_from_view;
gfx::DecomposedTransform origin_from_view_decomposed;
bool success =
gfx::DecomposeTransform(&origin_from_view_decomposed, origin_from_view);
DCHECK(success);
ret->pose->orientation = std::vector<float>{
static_cast<float>(origin_from_view_decomposed.quaternion.x()),
static_cast<float>(origin_from_view_decomposed.quaternion.y()),
static_cast<float>(origin_from_view_decomposed.quaternion.z()),
static_cast<float>(origin_from_view_decomposed.quaternion.w())};
ret->pose->position = std::vector<float>{
static_cast<float>(origin_from_view_decomposed.translate[0]),
static_cast<float>(origin_from_view_decomposed.translate[1]),
static_cast<float>(origin_from_view_decomposed.translate[2])};
}
return ret; return ret;
} }
......
...@@ -78,6 +78,12 @@ class MixedRealityRenderLoop : public XRCompositorCommon { ...@@ -78,6 +78,12 @@ class MixedRealityRenderLoop : public XRCompositorCommon {
ABI::Windows::Perception::Spatial::ISpatialCoordinateSystem> ABI::Windows::Perception::Spatial::ISpatialCoordinateSystem>
stage_origin_; stage_origin_;
bool stage_transform_needs_updating_ = false; bool stage_transform_needs_updating_ = false;
Microsoft::WRL::ComPtr<ABI::Windows::Perception::Spatial::
ISpatialLocatorAttachedFrameOfReference>
attached_;
bool emulated_position_ = false;
base::Optional<gfx::Transform> last_origin_from_attached_;
std::unique_ptr<MixedRealityWindow> window_; std::unique_ptr<MixedRealityWindow> window_;
mojom::VRDisplayInfoPtr current_display_info_; mojom::VRDisplayInfoPtr current_display_info_;
base::RepeatingCallback<void(mojom::VRDisplayInfoPtr)> base::RepeatingCallback<void(mojom::VRDisplayInfoPtr)>
......
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