1616#if MSFT_OPENXR  &&  WINDOWS_UWP 
1717using  Microsoft . MixedReality . OpenXR ; 
1818using  Microsoft . MixedReality . Toolkit . Windows . Input ; 
19+ using  Windows . UI . Input . Spatial ; 
1920#endif // MSFT_OPENXR && WINDOWS_UWP 
2021
2122namespace  Microsoft . MixedReality . Toolkit . XRSDK . OpenXR 
@@ -80,6 +81,7 @@ public override void Enable()
8081
8182#if MSFT_OPENXR  &&  WINDOWS_UWP 
8283            CreateGestureRecognizers ( ) ; 
84+             SpatialInteractionManager . SourcePressed  +=  SpatialInteractionManager_SourcePressed ; 
8385#endif // MSFT_OPENXR && WINDOWS_UWP 
8486
8587            base . Enable ( ) ; 
@@ -114,6 +116,26 @@ public override void Update()
114116            base . Update ( ) ; 
115117
116118            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+             } 
117139        } 
118140
119141        /// <inheritdoc /> 
@@ -140,6 +162,14 @@ public override void Disable()
140162#endif
141163            navigationGestureRecognizer  =  null ; 
142164
165+             SpatialInteractionManager . SourcePressed  -=  SpatialInteractionManager_SourcePressed ; 
166+ 
167+             if  ( voiceController  !=  null ) 
168+             { 
169+                 RemoveControllerFromScene ( voiceController ) ; 
170+                 voiceController  =  null ; 
171+             } 
172+ 
143173            base . Disable ( ) ; 
144174        } 
145175#endif // MSFT_OPENXR && WINDOWS_UWP 
@@ -529,5 +559,75 @@ private GenericXRSDKController FindMatchingController(GestureHandedness gestureH
529559#endif // MSFT_OPENXR && WINDOWS_UWP 
530560
531561        #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
532632    } 
533633} 
0 commit comments