16
16
#if MSFT_OPENXR && WINDOWS_UWP
17
17
using Microsoft . MixedReality . OpenXR ;
18
18
using Microsoft . MixedReality . Toolkit . Windows . Input ;
19
+ using Windows . UI . Input . Spatial ;
19
20
#endif // MSFT_OPENXR && WINDOWS_UWP
20
21
21
22
namespace Microsoft . MixedReality . Toolkit . XRSDK . OpenXR
@@ -80,6 +81,7 @@ public override void Enable()
80
81
81
82
#if MSFT_OPENXR && WINDOWS_UWP
82
83
CreateGestureRecognizers ( ) ;
84
+ SpatialInteractionManager . SourcePressed += SpatialInteractionManager_SourcePressed ;
83
85
#endif // MSFT_OPENXR && WINDOWS_UWP
84
86
85
87
base . Enable ( ) ;
@@ -114,6 +116,26 @@ public override void Update()
114
116
base . Update ( ) ;
115
117
116
118
CheckForGestures ( ) ;
119
+
120
+ if ( shouldSendVoiceEvents )
121
+ {
122
+ MicrosoftOpenXRGGVHand controller = GetOrAddVoiceController ( ) ;
123
+ if ( controller != null )
124
+ {
125
+ // RaiseOnInputDown for "select"
126
+ controller . UpdateVoiceState ( true ) ;
127
+ // RaiseOnInputUp for "select"
128
+ controller . UpdateVoiceState ( false ) ;
129
+
130
+ // On WMR, the voice recognizer does not actually register the phrase 'select'
131
+ // when you add it to the speech commands profile. Therefore, simulate
132
+ // the "select" voice command running to ensure that we get a select voice command
133
+ // registered. This is used by FocusProvider to detect when the select pointer is active.
134
+ Service ? . RaiseSpeechCommandRecognized ( controller . InputSource , RecognitionConfidenceLevel . High , TimeSpan . MinValue , DateTime . Now , new SpeechCommands ( "select" , KeyCode . Alpha1 , MixedRealityInputAction . None ) ) ;
135
+ }
136
+
137
+ shouldSendVoiceEvents = false ;
138
+ }
117
139
}
118
140
119
141
/// <inheritdoc />
@@ -140,6 +162,14 @@ public override void Disable()
140
162
#endif
141
163
navigationGestureRecognizer = null ;
142
164
165
+ SpatialInteractionManager . SourcePressed -= SpatialInteractionManager_SourcePressed ;
166
+
167
+ if ( voiceController != null )
168
+ {
169
+ RemoveControllerFromScene ( voiceController ) ;
170
+ voiceController = null ;
171
+ }
172
+
143
173
base . Disable ( ) ;
144
174
}
145
175
#endif // MSFT_OPENXR && WINDOWS_UWP
@@ -529,5 +559,75 @@ private GenericXRSDKController FindMatchingController(GestureHandedness gestureH
529
559
#endif // MSFT_OPENXR && WINDOWS_UWP
530
560
531
561
#endregion Gesture implementation
562
+
563
+ #region SpatialInteractionManager event and helpers
564
+
565
+ #if MSFT_OPENXR && WINDOWS_UWP
566
+ /// <summary>
567
+ /// SDK Interaction Source Pressed Event handler. Used only for voice.
568
+ /// </summary>
569
+ /// <param name="args">SDK source pressed event arguments</param>
570
+ private void SpatialInteractionManager_SourcePressed ( SpatialInteractionManager sender , SpatialInteractionSourceEventArgs args )
571
+ {
572
+ if ( args . State . Source . Kind == SpatialInteractionSourceKind . Voice )
573
+ {
574
+ shouldSendVoiceEvents = true ;
575
+ }
576
+ }
577
+
578
+ private MicrosoftOpenXRGGVHand voiceController = null ;
579
+ private bool shouldSendVoiceEvents = false ;
580
+
581
+ private MicrosoftOpenXRGGVHand GetOrAddVoiceController ( )
582
+ {
583
+ if ( voiceController != null )
584
+ {
585
+ return voiceController ;
586
+ }
587
+
588
+ IMixedRealityInputSource inputSource = Service ? . RequestNewGenericInputSource ( "Mixed Reality Voice" , sourceType : InputSourceType . Voice ) ;
589
+ MicrosoftOpenXRGGVHand detectedController = new MicrosoftOpenXRGGVHand ( TrackingState . NotTracked , Utilities . Handedness . None , inputSource ) ;
590
+
591
+ if ( ! detectedController . Enabled )
592
+ {
593
+ // Controller failed to be setup correctly.
594
+ // Return null so we don't raise the source detected.
595
+ return null ;
596
+ }
597
+
598
+ for ( int i = 0 ; i < detectedController . InputSource ? . Pointers ? . Length ; i ++ )
599
+ {
600
+ detectedController . InputSource . Pointers [ i ] . Controller = detectedController ;
601
+ }
602
+
603
+ Service ? . RaiseSourceDetected ( detectedController . InputSource , detectedController ) ;
604
+
605
+ voiceController = detectedController ;
606
+ return voiceController ;
607
+ }
608
+
609
+ private SpatialInteractionManager spatialInteractionManager = null ;
610
+
611
+ /// <summary>
612
+ /// Provides access to the current native SpatialInteractionManager.
613
+ /// </summary>
614
+ private SpatialInteractionManager SpatialInteractionManager
615
+ {
616
+ get
617
+ {
618
+ if ( spatialInteractionManager == null )
619
+ {
620
+ UnityEngine . WSA . Application . InvokeOnUIThread ( ( ) =>
621
+ {
622
+ spatialInteractionManager = SpatialInteractionManager . GetForCurrentView ( ) ;
623
+ } , true ) ;
624
+ }
625
+
626
+ return spatialInteractionManager ;
627
+ }
628
+ }
629
+ #endif // MSFT_OPENXR && WINDOWS_UWP
630
+
631
+ #endregion SpatialInteractionManager events
532
632
}
533
633
}
0 commit comments