22
33#pragma warning disable 0649
44using HTC . UnityPlugin . Utility ;
5+ using HTC . UnityPlugin . Vive ;
56using System ;
67using System . Collections . Generic ;
78using System . Text . RegularExpressions ;
@@ -78,10 +79,55 @@ private struct XRInputSubsystemProfile
7879 private VRModuleKnownXRLoader knownActiveLoader ;
7980 private VRModuleKnownXRInputSubsystem knownActiveInputSubsystem ;
8081 private IndexMap indexMap = new IndexMap ( ) ;
81- private uint uxrRightIndex = INVALID_DEVICE_INDEX ;
82- private uint uxrLeftIndex = INVALID_DEVICE_INDEX ;
8382 private uint moduleRightIndex = INVALID_DEVICE_INDEX ;
8483 private uint moduleLeftIndex = INVALID_DEVICE_INDEX ;
84+
85+ private enum RolePriority
86+ {
87+ Controller ,
88+ TrackedHand ,
89+ Tracker ,
90+ Other ,
91+ }
92+ private struct RoleIdx
93+ {
94+ public IVRModuleDeviceStateRW ds ;
95+ public RolePriority pri ;
96+ public uint index { get { return ds . deviceIndex ; } }
97+ public RoleIdx ( IVRModuleDeviceStateRW deviceState )
98+ {
99+ ds = deviceState ;
100+ switch ( deviceState . deviceClass )
101+ {
102+ case VRModuleDeviceClass . Controller : pri = RolePriority . Controller ; break ;
103+ case VRModuleDeviceClass . TrackedHand : pri = RolePriority . TrackedHand ; break ;
104+ case VRModuleDeviceClass . GenericTracker : pri = RolePriority . Tracker ; break ;
105+ default : pri = RolePriority . Other ; break ;
106+ }
107+ }
108+ }
109+ private List < RoleIdx > rightIndice = new List < RoleIdx > ( ) ;
110+ private List < RoleIdx > leftIndice = new List < RoleIdx > ( ) ;
111+ private static int CompareRoleIdx ( RoleIdx a , RoleIdx b )
112+ {
113+ var c = a . ds . isPoseValid . CompareTo ( b . ds . isPoseValid ) ;
114+ if ( c != 0 ) { return - c ; }
115+
116+ c = a . pri - b . pri ;
117+ if ( c != 0 ) { return c ; }
118+
119+ if ( a . pri == RolePriority . TrackedHand )
120+ {
121+ foreach ( var j in JointEnumArray . StaticEnums )
122+ {
123+ c = a . ds . handJoints [ j ] . isValid . CompareTo ( b . ds . handJoints [ j ] . isValid ) ;
124+ if ( c != 0 ) { return - c ; }
125+ }
126+ }
127+
128+ return a . ds . deviceIndex . CompareTo ( b . ds . deviceIndex ) ;
129+ }
130+
85131 private VRModule . SubmoduleBase . Collection submodules = new VRModule . SubmoduleBase . Collection (
86132 new ViveHandTrackingSubmodule ( ) ,
87133 new WaveHandTrackingSubmodule ( ) ,
@@ -90,11 +136,15 @@ private struct XRInputSubsystemProfile
90136
91137 private bool [ ] prevDeviceConnected = new bool [ VRModule . MAX_DEVICE_COUNT ] ;
92138 private bool [ ] currDeviceConnected = new bool [ VRModule . MAX_DEVICE_COUNT ] ;
139+ private int prevMaxConnectedIndex = - 1 ;
140+ private int currMaxConnectedIndex = - 1 ;
93141 private void FlushDeviceConnectedState ( )
94142 {
95143 var temp = prevDeviceConnected ;
96144 prevDeviceConnected = currDeviceConnected ;
97145 currDeviceConnected = temp ;
146+ prevMaxConnectedIndex = currMaxConnectedIndex ;
147+ currMaxConnectedIndex = - 1 ;
98148 Array . Clear ( currDeviceConnected , 0 , ( int ) VRModule . MAX_DEVICE_COUNT ) ;
99149 }
100150
@@ -144,6 +194,9 @@ public sealed override void BeforeRenderUpdate()
144194 uint deviceIndex ;
145195
146196 FlushDeviceState ( ) ;
197+ FlushDeviceConnectedState ( ) ;
198+ rightIndice . Clear ( ) ;
199+ leftIndice . Clear ( ) ;
147200
148201 InputDevices . GetDevices ( connectedDevices ) ;
149202
@@ -174,7 +227,7 @@ public sealed override void BeforeRenderUpdate()
174227
175228 SetupKnownDeviceModel ( currState ) ;
176229
177- Debug . LogFormat ( "Device connected: {0} / {1} / {2} / {3} / {4} / {5} ({6})" ,
230+ Debug . LogFormat ( "[UnityXRModule] Device connected: {0} / {1} / {2} / {3} / {4} / {5} ({6})" ,
178231 currState . deviceIndex ,
179232 currState . deviceClass ,
180233 currState . deviceModel ,
@@ -183,15 +236,6 @@ public sealed override void BeforeRenderUpdate()
183236 device . name ,
184237 device . characteristics ) ;
185238
186- if ( ( device . characteristics & InputDeviceCharacteristics . Right ) > 0u )
187- {
188- uxrRightIndex = deviceIndex ;
189- }
190- else if ( ( device . characteristics & InputDeviceCharacteristics . Left ) > 0u )
191- {
192- uxrLeftIndex = deviceIndex ;
193- }
194-
195239 UpdateNewConnectedInputDevice ( currState , device ) ;
196240 }
197241 else
@@ -202,7 +246,10 @@ public sealed override void BeforeRenderUpdate()
202246 currState . isConnected = true ;
203247 // update device Poses
204248 currState . isPoseValid = GetDeviceFeatureValueOrDefault ( device , CommonUsages . isTracked ) ;
205- if ( Vive . VIUSettings . preferUnityXRPointerPose )
249+ if ( ( device . characteristics & InputDeviceCharacteristics . Right ) != 0u ) { rightIndice . Add ( new RoleIdx ( currState ) ) ; }
250+ else if ( ( device . characteristics & InputDeviceCharacteristics . Left ) != 0u ) { leftIndice . Add ( new RoleIdx ( currState ) ) ; }
251+
252+ if ( VIUSettings . preferUnityXRPointerPose )
206253 {
207254 currState . position = GetDeviceFeatureValueOrDefault ( device , pointerPositionFeature , CommonUsages . devicePosition ) ;
208255 currState . rotation = GetDeviceFeatureValueOrDefault ( device , pointerRotationFeature , CommonUsages . deviceRotation ) ;
@@ -218,12 +265,13 @@ public sealed override void BeforeRenderUpdate()
218265 }
219266
220267 currDeviceConnected [ deviceIndex ] = true ;
268+ if ( currMaxConnectedIndex < ( int ) deviceIndex ) { currMaxConnectedIndex = ( int ) deviceIndex ; }
221269
222270 // TODO: update hand skeleton pose
223271 }
224272
225273 // unmap index for disconnected device state
226- for ( uint i = 0u , imax = VRModule . MAX_DEVICE_COUNT ; i < imax ; ++ i )
274+ for ( uint i = 0u , imax = ( uint ) ( prevMaxConnectedIndex + 1 ) ; i < imax ; ++ i )
227275 {
228276 if ( prevDeviceConnected [ i ] && ! currDeviceConnected [ i ] )
229277 {
@@ -233,35 +281,55 @@ public sealed override void BeforeRenderUpdate()
233281 }
234282 else
235283 {
236- Debug . LogWarning ( "[UnityXRModule] Disconnected device [" + i + "] already unmapped" ) ;
284+ Debug . LogWarning ( "[UnityXRModule] Device disconnected: [" + i + "] already unmapped" ) ;
237285 }
238286
239287 if ( TryGetValidDeviceState ( i , out prevState , out currState ) && currState . isConnected )
240288 {
241289 currState . Reset ( ) ;
242- if ( uxrRightIndex == i ) { uxrRightIndex = INVALID_DEVICE_INDEX ; }
243- if ( uxrLeftIndex == i ) { uxrLeftIndex = INVALID_DEVICE_INDEX ; }
244290 }
245291 else
246292 {
247- Debug . LogWarning ( "[UnityXRModule] Disconnected device [" + i + "] already been reset" ) ;
293+ Debug . LogWarning ( "[UnityXRModule] Device disconnected: [" + i + "] already been reset" ) ;
248294 }
295+
296+ Debug . LogFormat ( "[UnityXRModule] Device disconnected: {0} / {1} / {2} / {3} / {4}" ,
297+ prevState . deviceIndex ,
298+ prevState . deviceClass ,
299+ prevState . deviceModel ,
300+ prevState . modelNumber ,
301+ prevState . serialNumber ) ;
249302 }
250303 }
251304
252- FlushDeviceConnectedState ( ) ;
253-
254305 submodules . UpdateModulesDeviceConnectionAndPoses ( ) ;
306+ for ( int i = 0 , imax = submodules . ModuleCount ; i < imax ; ++ i )
307+ {
308+ if ( ! submodules [ i ] . isActivated ) { continue ; }
309+ if ( TryGetValidDeviceState ( submodules [ i ] . GetRightHandedIndex ( ) , out prevState , out currState ) && currState . isConnected )
310+ {
311+ rightIndice . Add ( new RoleIdx ( currState ) ) ;
312+ }
313+ if ( TryGetValidDeviceState ( submodules [ i ] . GetLeftHandedIndex ( ) , out prevState , out currState ) && currState . isConnected )
314+ {
315+ leftIndice . Add ( new RoleIdx ( currState ) ) ;
316+ }
317+ }
255318
256319 // process hand role
257- var subRightIndex = submodules . GetFirstRightHandedIndex ( ) ;
258- var currentRight = ( subRightIndex == INVALID_DEVICE_INDEX || ( TryGetValidDeviceState ( uxrRightIndex , out prevState , out currState ) && currState . isPoseValid && currState . deviceClass == VRModuleDeviceClass . Controller ) ) ? uxrRightIndex : subRightIndex ;
259- var subLeftIndex = submodules . GetFirstLeftHandedIndex ( ) ;
260- var currentLeft = ( subLeftIndex == INVALID_DEVICE_INDEX || ( TryGetValidDeviceState ( uxrLeftIndex , out prevState , out currState ) && currState . isPoseValid && currState . deviceClass == VRModuleDeviceClass . Controller ) ) ? uxrLeftIndex : subLeftIndex ;
261- var roleChanged = ChangeProp . Set ( ref moduleRightIndex , currentRight ) ;
262- roleChanged |= ChangeProp . Set ( ref moduleLeftIndex , currentLeft ) ;
263-
264- if ( roleChanged )
320+ var newRightIndex = INVALID_DEVICE_INDEX ;
321+ if ( rightIndice . Count != 0 )
322+ {
323+ if ( rightIndice . Count != 1 ) { rightIndice . Sort ( CompareRoleIdx ) ; }
324+ newRightIndex = rightIndice [ 0 ] . index ;
325+ }
326+ var newLeftIndex = INVALID_DEVICE_INDEX ;
327+ if ( leftIndice . Count != 0 )
328+ {
329+ if ( leftIndice . Count != 1 ) { leftIndice . Sort ( CompareRoleIdx ) ; }
330+ newLeftIndex = leftIndice [ 0 ] . index ;
331+ }
332+ if ( ChangeProp . Set ( ref moduleRightIndex , newRightIndex ) | ChangeProp . Set ( ref moduleLeftIndex , newLeftIndex ) )
265333 {
266334 InvokeControllerRoleChangedEvent ( ) ;
267335 }
@@ -327,6 +395,11 @@ protected static VRModuleDeviceClass GetDeviceClass(string name, InputDeviceChar
327395 return VRModuleDeviceClass . GenericTracker ;
328396 }
329397
398+ if ( ( characteristics & InputDeviceCharacteristics . HandTracking ) != 0 )
399+ {
400+ return VRModuleDeviceClass . TrackedHand ;
401+ }
402+
330403 return VRModuleDeviceClass . Invalid ;
331404 }
332405
@@ -335,13 +408,22 @@ private static void SetAllXRInputSubsystemTrackingOriginMode(TrackingOriginModeF
335408 var activeSubsys = ListPool < XRInputSubsystem > . Get ( ) ;
336409 try
337410 {
411+ #if UNITY_6000_0_OR_NEWER
412+ SubsystemManager . GetSubsystems ( activeSubsys ) ;
413+ #else
338414 SubsystemManager . GetInstances ( activeSubsys ) ;
415+ #endif
339416 foreach ( var subsys in activeSubsys )
340417 {
341418 if ( ! subsys . running ) { continue ; }
342419 if ( ! subsys . TrySetTrackingOriginMode ( value ) )
343420 {
344- Debug . LogWarning ( "Failed to set TrackingOriginModeFlags(" + value + ") to XRInputSubsystem: " + subsys . SubsystemDescriptor . id ) ;
421+ #if UNITY_6000_0_OR_NEWER
422+ var subsysId = subsys . subsystemDescriptor . id ;
423+ #else
424+ var subsysId = subsys . SubsystemDescriptor . id ;
425+ #endif
426+ Debug . LogWarning ( "Failed to set TrackingOriginModeFlags(" + value + ") to XRInputSubsystem: " + subsysId ) ;
345427 }
346428 }
347429 }
@@ -425,7 +507,11 @@ protected void UpdateLockPhysicsUpdateRate()
425507 var displaySystems = ListPool < XRDisplaySubsystem > . Get ( ) ;
426508 try
427509 {
510+ #if UNITY_6000_0_OR_NEWER
511+ SubsystemManager . GetSubsystems ( displaySystems ) ;
512+ #else
428513 SubsystemManager . GetInstances ( displaySystems ) ;
514+ #endif
429515
430516 var minRefreshRate = float . MaxValue ;
431517 foreach ( XRDisplaySubsystem system in displaySystems )
0 commit comments