From 907082ff4bfa6e2df2a3b3befde8d8b33326cda0 Mon Sep 17 00:00:00 2001 From: StephenHodgson Date: Mon, 22 Apr 2019 15:50:17 -0700 Subject: [PATCH] Fixed an issue where there was a 3rd untracked controller in the scene. Now the wmr controller data provider raises source found/lost when tracking is found/lost. --- .../WindowsMixedRealityDataProvider.cs | 141 ++++++++++-------- 1 file changed, 81 insertions(+), 60 deletions(-) diff --git a/XRTK.WindowsMixedReality/Assets/XRTK.WindowsMixedReality/Controllers/WindowsMixedRealityDataProvider.cs b/XRTK.WindowsMixedReality/Assets/XRTK.WindowsMixedReality/Controllers/WindowsMixedRealityDataProvider.cs index 15fb41f..f6de9de 100644 --- a/XRTK.WindowsMixedReality/Assets/XRTK.WindowsMixedReality/Controllers/WindowsMixedRealityDataProvider.cs +++ b/XRTK.WindowsMixedReality/Assets/XRTK.WindowsMixedReality/Controllers/WindowsMixedRealityDataProvider.cs @@ -68,7 +68,7 @@ public WindowsMixedRealityDataProvider(string name, uint priority, WindowsMixedR /// /// Cache of the states captured from the Unity InteractionManager for UWP /// - InteractionSourceState[] interactionManagerStates = new InteractionSourceState[MaxInteractionSourceStates]; + private readonly InteractionSourceState[] interactionManagerStates = new InteractionSourceState[MaxInteractionSourceStates]; /// /// The number of states captured most recently @@ -295,12 +295,16 @@ public override void Enable() // NOTE: We update the source state data, in case an app wants to query it on source detected. for (var i = 0; i < numInteractionManagerStates; i++) { - var controller = GetController(interactionManagerStates[i].source); + var state = interactionManagerStates[i]; + + if (state.sourcePose.positionAccuracy == InteractionSourcePositionAccuracy.None) { continue; } + + var controller = GetController(state.source, true); if (controller != null) { MixedRealityToolkit.InputSystem?.RaiseSourceDetected(controller.InputSource, controller); - controller.UpdateController(interactionManagerStates[i]); + controller.UpdateController(state); } } @@ -321,7 +325,22 @@ public override void Update() for (var i = 0; i < numInteractionManagerStates; i++) { - GetController(interactionManagerStates[i].source, false)?.UpdateController(interactionManagerStates[i]); + var state = interactionManagerStates[i]; + var isTracked = state.sourcePose.positionAccuracy != InteractionSourcePositionAccuracy.None; + var raiseSourceDetected = !activeControllers.ContainsKey(state.source.id); + var controller = GetController(state.source, raiseSourceDetected && isTracked); + + if (controller != null && raiseSourceDetected) + { + MixedRealityToolkit.InputSystem?.RaiseSourceDetected(controller.InputSource, controller); + } + + controller?.UpdateController(state); + + if (!isTracked) + { + RemoveController(state); + } } LastInteractionManagerStateReading = interactionManagerStates; @@ -376,7 +395,7 @@ protected override void OnDispose(bool finalizing) /// Source State provided by the SDK /// Should the Source be added as a controller if it isn't found? /// New or Existing Controller Input Source - private WindowsMixedRealityController GetController(InteractionSource interactionSource, bool addController = true) + private WindowsMixedRealityController GetController(InteractionSource interactionSource, bool addController = false) { //If a device is already registered with the ID provided, just return it. if (activeControllers.ContainsKey(interactionSource.id)) @@ -403,9 +422,9 @@ private WindowsMixedRealityController GetController(InteractionSource interactio } var pointers = interactionSource.supportsPointing ? RequestPointers(typeof(WindowsMixedRealityController), controllingHand) : null; - string nameModifier = controllingHand == Handedness.None ? interactionSource.kind.ToString() : controllingHand.ToString(); + var nameModifier = controllingHand == Handedness.None ? interactionSource.kind.ToString() : controllingHand.ToString(); var inputSource = MixedRealityToolkit.InputSystem?.RequestNewGenericInputSource($"Mixed Reality Controller {nameModifier}", pointers); - var detectedController = new WindowsMixedRealityController(TrackingState.NotTracked, controllingHand, inputSource); + var detectedController = new WindowsMixedRealityController(TrackingState.NotApplicable, controllingHand, inputSource); if (!detectedController.SetupConfiguration(typeof(WindowsMixedRealityController))) { @@ -428,51 +447,49 @@ private WindowsMixedRealityController GetController(InteractionSource interactio private static async void TryRenderControllerModel(InteractionSource interactionSource, WindowsMixedRealityController controller) { #if WINDOWS_UWP - if (UnityEngine.XR.WSA.HolographicSettings.IsDisplayOpaque) + if (!UnityEngine.XR.WSA.HolographicSettings.IsDisplayOpaque) { return; } + IRandomAccessStreamWithContentType stream = null; + + if (!WindowsApiChecker.UniversalApiContractV5_IsAvailable) { return; } + + await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, DispatchedHandler); + + async void DispatchedHandler() { - IRandomAccessStreamWithContentType stream = null; + byte[] glbModelData = null; + var sources = SpatialInteractionManager + .GetForCurrentView() + .GetDetectedSourcesAtTimestamp( + PerceptionTimestampHelper.FromHistoricalTargetTime(DateTimeOffset.Now)); + + for (var i = 0; i < sources?.Count; i++) + { + if (sources[i].Source.Id.Equals(interactionSource.id)) + { + stream = await sources[i].Source.Controller.TryGetRenderableModelAsync(); + break; + } + } - if (WindowsApiChecker.UniversalApiContractV5_IsAvailable) + if (stream != null) { - async void DispatchedHandler() + glbModelData = new byte[stream.Size]; + + using (var reader = new DataReader(stream)) { - byte[] glbModelData = null; - var sources = SpatialInteractionManager - .GetForCurrentView() - .GetDetectedSourcesAtTimestamp( - PerceptionTimestampHelper.FromHistoricalTargetTime(DateTimeOffset.Now)); - - for (var i = 0; i < sources?.Count; i++) - { - if (sources[i].Source.Id.Equals(interactionSource.id)) - { - stream = await sources[i].Source.Controller.TryGetRenderableModelAsync(); - break; - } - } - - if (stream != null) - { - glbModelData = new byte[stream.Size]; - - using (var reader = new DataReader(stream)) - { - await reader.LoadAsync((uint)stream.Size); - reader.ReadBytes(glbModelData); - } - - stream.Dispose(); - } - else - { - Debug.LogError("Failed to load model data!"); - } - - await controller.TryRenderControllerModelAsync(typeof(WindowsMixedRealityController), glbModelData, interactionSource.kind == InteractionSourceKind.Hand); + await reader.LoadAsync((uint)stream.Size); + reader.ReadBytes(glbModelData); } - await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, DispatchedHandler); + stream.Dispose(); + } + else + { + Debug.LogError("Failed to load model data!"); } + + // This really isn't an error, we actually can call TryRenderControllerModelAsync here. + await controller.TryRenderControllerModelAsync(typeof(WindowsMixedRealityController), glbModelData, interactionSource.kind == InteractionSourceKind.Hand); } #else await controller.TryRenderControllerModelAsync(typeof(WindowsMixedRealityController), null, interactionSource.kind == InteractionSourceKind.Hand); @@ -485,7 +502,7 @@ async void DispatchedHandler() /// Source State provided by the SDK to remove private void RemoveController(InteractionSourceState interactionSourceState) { - var controller = GetController(interactionSourceState.source, false); + var controller = GetController(interactionSourceState.source); if (controller != null) { @@ -505,9 +522,13 @@ private void RemoveController(InteractionSourceState interactionSourceState) /// SDK source detected event arguments private void InteractionManager_InteractionSourceDetected(InteractionSourceDetectedEventArgs args) { - bool raiseSourceDetected = !activeControllers.ContainsKey(args.state.source.id); + if (args.state.sourcePose.positionAccuracy == InteractionSourcePositionAccuracy.None) + { + return; + } - var controller = GetController(args.state.source); + var raiseSourceDetected = !activeControllers.ContainsKey(args.state.source.id); + var controller = GetController(args.state.source, true); if (controller != null && raiseSourceDetected) { @@ -532,7 +553,7 @@ private void InteractionManager_InteractionSourceLost(InteractionSourceLostEvent private void GestureRecognizer_Tapped(TappedEventArgs args) { - var controller = GetController(args.source, false); + var controller = GetController(args.source); if (controller != null) { @@ -551,7 +572,7 @@ private void GestureRecognizer_Tapped(TappedEventArgs args) private void GestureRecognizer_HoldStarted(HoldStartedEventArgs args) { - var controller = GetController(args.source, false); + var controller = GetController(args.source); if (controller != null) { MixedRealityToolkit.InputSystem?.RaiseGestureStarted(controller, holdAction); @@ -560,7 +581,7 @@ private void GestureRecognizer_HoldStarted(HoldStartedEventArgs args) private void GestureRecognizer_HoldCompleted(HoldCompletedEventArgs args) { - var controller = GetController(args.source, false); + var controller = GetController(args.source); if (controller != null) { MixedRealityToolkit.InputSystem.RaiseGestureCompleted(controller, holdAction); @@ -569,7 +590,7 @@ private void GestureRecognizer_HoldCompleted(HoldCompletedEventArgs args) private void GestureRecognizer_HoldCanceled(HoldCanceledEventArgs args) { - var controller = GetController(args.source, false); + var controller = GetController(args.source); if (controller != null) { MixedRealityToolkit.InputSystem.RaiseGestureCanceled(controller, holdAction); @@ -578,7 +599,7 @@ private void GestureRecognizer_HoldCanceled(HoldCanceledEventArgs args) private void GestureRecognizer_ManipulationStarted(ManipulationStartedEventArgs args) { - var controller = GetController(args.source, false); + var controller = GetController(args.source); if (controller != null) { MixedRealityToolkit.InputSystem.RaiseGestureStarted(controller, manipulationAction); @@ -587,7 +608,7 @@ private void GestureRecognizer_ManipulationStarted(ManipulationStartedEventArgs private void GestureRecognizer_ManipulationUpdated(ManipulationUpdatedEventArgs args) { - var controller = GetController(args.source, false); + var controller = GetController(args.source); if (controller != null) { MixedRealityToolkit.InputSystem.RaiseGestureUpdated(controller, manipulationAction, args.cumulativeDelta); @@ -596,7 +617,7 @@ private void GestureRecognizer_ManipulationUpdated(ManipulationUpdatedEventArgs private void GestureRecognizer_ManipulationCompleted(ManipulationCompletedEventArgs args) { - var controller = GetController(args.source, false); + var controller = GetController(args.source); if (controller != null) { MixedRealityToolkit.InputSystem.RaiseGestureCompleted(controller, manipulationAction, args.cumulativeDelta); @@ -605,7 +626,7 @@ private void GestureRecognizer_ManipulationCompleted(ManipulationCompletedEventA private void GestureRecognizer_ManipulationCanceled(ManipulationCanceledEventArgs args) { - var controller = GetController(args.source, false); + var controller = GetController(args.source); if (controller != null) { MixedRealityToolkit.InputSystem.RaiseGestureCanceled(controller, manipulationAction); @@ -618,7 +639,7 @@ private void GestureRecognizer_ManipulationCanceled(ManipulationCanceledEventArg private void NavigationGestureRecognizer_NavigationStarted(NavigationStartedEventArgs args) { - var controller = GetController(args.source, false); + var controller = GetController(args.source); if (controller != null) { MixedRealityToolkit.InputSystem.RaiseGestureStarted(controller, navigationAction); @@ -627,7 +648,7 @@ private void NavigationGestureRecognizer_NavigationStarted(NavigationStartedEven private void NavigationGestureRecognizer_NavigationUpdated(NavigationUpdatedEventArgs args) { - var controller = GetController(args.source, false); + var controller = GetController(args.source); if (controller != null) { MixedRealityToolkit.InputSystem.RaiseGestureUpdated(controller, navigationAction, args.normalizedOffset); @@ -636,7 +657,7 @@ private void NavigationGestureRecognizer_NavigationUpdated(NavigationUpdatedEven private void NavigationGestureRecognizer_NavigationCompleted(NavigationCompletedEventArgs args) { - var controller = GetController(args.source, false); + var controller = GetController(args.source); if (controller != null) { MixedRealityToolkit.InputSystem.RaiseGestureCompleted(controller, navigationAction, args.normalizedOffset); @@ -645,7 +666,7 @@ private void NavigationGestureRecognizer_NavigationCompleted(NavigationCompleted private void NavigationGestureRecognizer_NavigationCanceled(NavigationCanceledEventArgs args) { - var controller = GetController(args.source, false); + var controller = GetController(args.source); if (controller != null) { MixedRealityToolkit.InputSystem.RaiseGestureCanceled(controller, navigationAction);