Commit 8081952c authored by Bill Orr's avatar Bill Orr Committed by Commit Bot

Fix Windows mixed reality tracking loss handling

When tracking is regained, we should go back to the original origin.
This means we should use an anchor rather than a
SpatialStationaryFrameOfReference.

Bug: 965528
Change-Id: I8183b141cf4f9931a50866da4f2f97b54d43289e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1633990Reviewed-by: default avatarAlexander Cooper <alcooper@chromium.org>
Commit-Queue: Bill Orr <billorr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#664400}
parent 732a05e3
...@@ -249,7 +249,8 @@ void MixedRealityRenderLoop::StopRuntime() { ...@@ -249,7 +249,8 @@ void MixedRealityRenderLoop::StopRuntime() {
if (window_) if (window_)
ShowWindow(window_->hwnd(), SW_HIDE); ShowWindow(window_->hwnd(), SW_HIDE);
holographic_space_ = nullptr; holographic_space_ = nullptr;
origin_ = nullptr; anchor_origin_ = nullptr;
stationary_origin_ = nullptr;
last_origin_from_attached_ = base::nullopt; last_origin_from_attached_ = base::nullopt;
attached_ = nullptr; attached_ = nullptr;
ClearStageStatics(); ClearStageStatics();
...@@ -298,7 +299,11 @@ void MixedRealityRenderLoop::InitializeOrigin() { ...@@ -298,7 +299,11 @@ void MixedRealityRenderLoop::InitializeOrigin() {
if (!stationary_frame) if (!stationary_frame)
return; return;
origin_ = stationary_frame->CoordinateSystem(); stationary_origin_ = stationary_frame->CoordinateSystem();
// Instead of using the stationary_frame, use an anchor.
anchor_origin_ =
WMRSpatialAnchorFactory::TryCreateRelativeTo(stationary_origin_.get());
} }
void MixedRealityRenderLoop::ClearStageOrigin() { void MixedRealityRenderLoop::ClearStageOrigin() {
...@@ -387,7 +392,8 @@ void MixedRealityRenderLoop::OnSessionStart() { ...@@ -387,7 +392,8 @@ void MixedRealityRenderLoop::OnSessionStart() {
LogViewerType(VrViewerType::WINDOWS_MIXED_REALITY_UNKNOWN); LogViewerType(VrViewerType::WINDOWS_MIXED_REALITY_UNKNOWN);
// Each session should start with new origins. // Each session should start with new origins.
origin_ = nullptr; stationary_origin_ = nullptr;
anchor_origin_ = nullptr;
attached_ = nullptr; attached_ = nullptr;
last_origin_from_attached_ = base::nullopt; last_origin_from_attached_ = base::nullopt;
...@@ -427,12 +433,13 @@ mojom::XRGamepadDataPtr MixedRealityRenderLoop::GetNextGamepadData() { ...@@ -427,12 +433,13 @@ mojom::XRGamepadDataPtr MixedRealityRenderLoop::GetNextGamepadData() {
return nullptr; return nullptr;
} }
if (!origin_) { if (!anchor_origin_) {
WMRLogging::TraceError(WMRErrorLocation::kGamepadMissingOrigin); WMRLogging::TraceError(WMRErrorLocation::kGamepadMissingOrigin);
return nullptr; return nullptr;
} }
return input_helper_->GetWebVRGamepadData(origin_.get(), timestamp_.get()); return input_helper_->GetWebVRGamepadData(anchor_origin_.get(),
timestamp_.get());
} }
struct EyeToWorldDecomposed { struct EyeToWorldDecomposed {
...@@ -586,7 +593,7 @@ void MixedRealityRenderLoop::UpdateWMRDataForNextFrame() { ...@@ -586,7 +593,7 @@ void MixedRealityRenderLoop::UpdateWMRDataForNextFrame() {
return; return;
// Make sure we have an origin. // Make sure we have an origin.
if (!origin_) { if (!anchor_origin_) {
InitializeOrigin(); InitializeOrigin();
} }
...@@ -681,10 +688,11 @@ bool MixedRealityRenderLoop::UpdateStageParameters() { ...@@ -681,10 +688,11 @@ bool MixedRealityRenderLoop::UpdateStageParameters() {
// SpatialStageFrameOfReference.CurrentChanged to also re-calculate this. // SpatialStageFrameOfReference.CurrentChanged to also re-calculate this.
bool changed = false; bool changed = false;
if (stage_transform_needs_updating_) { if (stage_transform_needs_updating_) {
if (!(stage_origin_ && origin_) && current_display_info_->stageParameters) { if (!(stage_origin_ && anchor_origin_) &&
current_display_info_->stageParameters) {
changed = true; changed = true;
current_display_info_->stageParameters = nullptr; current_display_info_->stageParameters = nullptr;
} else if (stage_origin_ && origin_) { } else if (stage_origin_ && anchor_origin_) {
changed = true; changed = true;
current_display_info_->stageParameters = nullptr; current_display_info_->stageParameters = nullptr;
...@@ -692,7 +700,8 @@ bool MixedRealityRenderLoop::UpdateStageParameters() { ...@@ -692,7 +700,8 @@ bool MixedRealityRenderLoop::UpdateStageParameters() {
mojom::VRStageParameters::New(); mojom::VRStageParameters::New();
Matrix4x4 origin_to_stage; Matrix4x4 origin_to_stage;
if (!origin_->TryGetTransformTo(stage_origin_.get(), &origin_to_stage)) { if (!anchor_origin_->TryGetTransformTo(stage_origin_.get(),
&origin_to_stage)) {
// We failed to get a transform between the two, so force a // We failed to get a transform between the two, so force a
// recalculation of the stage origin and leave the stageParameters null. // recalculation of the stage origin and leave the stageParameters null.
ClearStageOrigin(); ClearStageOrigin();
...@@ -728,7 +737,7 @@ mojom::XRFrameDataPtr MixedRealityRenderLoop::GetNextFrameData() { ...@@ -728,7 +737,7 @@ mojom::XRFrameDataPtr MixedRealityRenderLoop::GetNextFrameData() {
mojom::XRFrameDataPtr ret = mojom::XRFrameDataPtr ret =
CreateDefaultFrameData(timestamp_.get(), next_frame_id_); CreateDefaultFrameData(timestamp_.get(), next_frame_id_);
if ((!attached_ && !origin_) || !pose_) { if ((!attached_ && !anchor_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
...@@ -743,13 +752,15 @@ mojom::XRFrameDataPtr MixedRealityRenderLoop::GetNextFrameData() { ...@@ -743,13 +752,15 @@ mojom::XRFrameDataPtr MixedRealityRenderLoop::GetNextFrameData() {
ABI::Windows::Graphics::Holographic::HolographicStereoTransform view; ABI::Windows::Graphics::Holographic::HolographicStereoTransform view;
bool got_view = false; bool got_view = false;
if (origin_ && pose_->TryGetViewTransform(origin_.get(), &view)) { if (anchor_origin_ &&
pose_->TryGetViewTransform(anchor_origin_.get(), &view)) {
got_view = true; got_view = true;
// TODO(http://crbug.com/931393): Send down emulated_position_, and report // TODO(http://crbug.com/931393): Send down emulated_position_, and report
// reset events when this changes. // reset events when this changes.
emulated_position_ = false; emulated_position_ = false;
ABI::Windows::Foundation::Numerics::Matrix4x4 transform; ABI::Windows::Foundation::Numerics::Matrix4x4 transform;
if (attached_coordinates->TryGetTransformTo(origin_.get(), &transform)) { if (attached_coordinates->TryGetTransformTo(anchor_origin_.get(),
&transform)) {
last_origin_from_attached_ = gfx::Transform( last_origin_from_attached_ = gfx::Transform(
transform.M11, transform.M21, transform.M31, transform.M41, transform.M11, transform.M21, transform.M31, transform.M41,
transform.M12, transform.M22, transform.M32, transform.M42, transform.M12, transform.M22, transform.M32, transform.M42,
...@@ -823,7 +834,7 @@ mojom::XRFrameDataPtr MixedRealityRenderLoop::GetNextFrameData() { ...@@ -823,7 +834,7 @@ mojom::XRFrameDataPtr MixedRealityRenderLoop::GetNextFrameData() {
} }
ret->pose->input_state = ret->pose->input_state =
input_helper_->GetInputState(origin_.get(), timestamp_.get()); input_helper_->GetInputState(anchor_origin_.get(), timestamp_.get());
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;
......
...@@ -90,8 +90,9 @@ class MixedRealityRenderLoop : public XRCompositorCommon { ...@@ -90,8 +90,9 @@ class MixedRealityRenderLoop : public XRCompositorCommon {
std::unique_ptr<WMRHolographicSpace> holographic_space_; std::unique_ptr<WMRHolographicSpace> holographic_space_;
std::unique_ptr<WMRStageOrigin> spatial_stage_; std::unique_ptr<WMRStageOrigin> spatial_stage_;
std::unique_ptr<WMRCoordinateSystem> origin_; std::unique_ptr<WMRCoordinateSystem> stationary_origin_;
std::unique_ptr<WMRCoordinateSystem> stage_origin_; std::unique_ptr<WMRCoordinateSystem> stage_origin_;
std::unique_ptr<WMRCoordinateSystem> anchor_origin_;
bool stage_transform_needs_updating_ = false; bool stage_transform_needs_updating_ = false;
std::unique_ptr<WMRAttachedOrigin> attached_; std::unique_ptr<WMRAttachedOrigin> attached_;
bool emulated_position_ = false; bool emulated_position_ = false;
......
...@@ -25,6 +25,8 @@ using SpatialMovementRange = ...@@ -25,6 +25,8 @@ using SpatialMovementRange =
using ABI::Windows::Foundation::IEventHandler; using ABI::Windows::Foundation::IEventHandler;
using ABI::Windows::Foundation::IReference; using ABI::Windows::Foundation::IReference;
using ABI::Windows::Graphics::Holographic::IHolographicSpace; using ABI::Windows::Graphics::Holographic::IHolographicSpace;
using ABI::Windows::Perception::Spatial::ISpatialAnchor;
using ABI::Windows::Perception::Spatial::ISpatialAnchorStatics;
using ABI::Windows::Perception::Spatial::ISpatialCoordinateSystem; using ABI::Windows::Perception::Spatial::ISpatialCoordinateSystem;
using ABI::Windows::Perception::Spatial::ISpatialLocator; using ABI::Windows::Perception::Spatial::ISpatialLocator;
using ABI::Windows::Perception::Spatial:: using ABI::Windows::Perception::Spatial::
...@@ -122,6 +124,34 @@ std::unique_ptr<WMRStageStatics> WMRStageStaticsFactory::Create() { ...@@ -122,6 +124,34 @@ std::unique_ptr<WMRStageStatics> WMRStageStaticsFactory::Create() {
return std::make_unique<WMRStageStaticsImpl>(stage_statics); return std::make_unique<WMRStageStaticsImpl>(stage_statics);
} }
std::unique_ptr<WMRCoordinateSystem>
WMRSpatialAnchorFactory::TryCreateRelativeTo(WMRCoordinateSystem* origin) {
if (MixedRealityDeviceStatics::ShouldUseMocks()) {
MockWMRStationaryOrigin origin;
return origin.CoordinateSystem();
}
ComPtr<ISpatialAnchorStatics> anchor_statics;
base::win::ScopedHString spatial_anchor_string =
base::win::ScopedHString::Create(
RuntimeClass_Windows_Perception_Spatial_SpatialAnchor);
HRESULT hr = base::win::RoGetActivationFactory(spatial_anchor_string.get(),
IID_PPV_ARGS(&anchor_statics));
if (FAILED(hr))
return nullptr;
ComPtr<ISpatialAnchor> anchor;
hr = anchor_statics->TryCreateRelativeTo(origin->GetRawPtr(), &anchor);
if (FAILED(hr) || !anchor)
return nullptr;
// Make a WMRCoordinateSystemImpl wrapping the coordinate system.
ComPtr<ISpatialCoordinateSystem> coordinate_system;
hr = anchor->get_CoordinateSystem(&coordinate_system);
DCHECK(SUCCEEDED(hr));
return std::make_unique<WMRCoordinateSystemImpl>(coordinate_system);
}
std::unique_ptr<WMRInputManager> WMRInputManagerFactory::GetForWindow( std::unique_ptr<WMRInputManager> WMRInputManagerFactory::GetForWindow(
HWND hwnd) { HWND hwnd) {
if (MixedRealityDeviceStatics::ShouldUseMocks()) { if (MixedRealityDeviceStatics::ShouldUseMocks()) {
......
...@@ -25,6 +25,12 @@ class WMRStageStaticsFactory { ...@@ -25,6 +25,12 @@ class WMRStageStaticsFactory {
static std::unique_ptr<WMRStageStatics> Create(); static std::unique_ptr<WMRStageStatics> Create();
}; };
class WMRSpatialAnchorFactory {
public:
static std::unique_ptr<WMRCoordinateSystem> TryCreateRelativeTo(
WMRCoordinateSystem* origin);
};
class WMRInputManagerFactory { class WMRInputManagerFactory {
public: public:
static std::unique_ptr<WMRInputManager> GetForWindow(HWND hwnd); static std::unique_ptr<WMRInputManager> GetForWindow(HWND hwnd);
......
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