@@ -68,7 +68,11 @@ protected override void OnEnable()
6868 }
6969
7070 // If we already found our subsystem, just return
71- if ( handSubsystem != null && handSubsystem . running ) { return ; }
71+ if ( handSubsystem != null && handSubsystem . running )
72+ {
73+ handSubsystem . updatedHands += OnHandsUpdated ;
74+ return ;
75+ }
7276
7377 List < XRHandSubsystem > subsystems = XRSubsystemHelpers . GetAllSubsystems < XRHandSubsystem > ( ) ;
7478 foreach ( XRHandSubsystem subsystem in subsystems )
@@ -77,6 +81,7 @@ protected override void OnEnable()
7781 {
7882 Debug . Log ( $ "Using { provider . handMeshDataSupplier . GetType ( ) } for hand visualization.") ;
7983 handSubsystem = subsystem ;
84+ handSubsystem . updatedHands += OnHandsUpdated ;
8085 return ;
8186 }
8287 }
@@ -100,6 +105,16 @@ protected override void OnEnable()
100105 enabled = false ;
101106 }
102107
108+ protected override void OnDisable ( )
109+ {
110+ base . OnDisable ( ) ;
111+
112+ if ( handSubsystem != null )
113+ {
114+ handSubsystem . updatedHands -= OnHandsUpdated ;
115+ }
116+ }
117+
103118 protected void Update ( )
104119 {
105120 if ( ! ShouldRenderHand ( ) )
@@ -112,57 +127,10 @@ protected void Update()
112127 return ;
113128 }
114129
130+ // This path is handled in the OnHandsUpdated event handler
115131 if ( handSubsystem != null && handSubsystem . running )
116132 {
117- XRHandMeshDataQueryParams queryParams = new ( )
118- {
119- allocator = Unity . Collections . Allocator . Temp ,
120- } ;
121-
122- if ( ( handSubsystem . updateSuccessFlags & updateSuccessFlags ) != 0
123- && ( lastUpdatedFrame == Time . frameCount || handSubsystem . TryGetMeshData ( out result , ref queryParams ) ) )
124- {
125- lastUpdatedFrame = Time . frameCount ;
126- XRHandMeshData handMeshData = HandNode == XRNode . LeftHand ? result . leftHand : result . rightHand ;
127- handRenderer . enabled = true ;
128- Mesh mesh = meshFilter . mesh ;
129-
130- if ( handMeshData . positions . Length > 0 && handMeshData . indices . Length > 0 )
131- {
132- mesh . SetVertices ( handMeshData . positions ) ;
133- Unity . Collections . NativeArray < int > indices = handMeshData . indices ;
134- // This API appears to return CCW triangles, but Unity expects CW triangles
135- for ( int i = 0 ; i < indices . Length ; i += 3 )
136- {
137- ( indices [ i + 1 ] , indices [ i + 2 ] ) = ( indices [ i + 2 ] , indices [ i + 1 ] ) ;
138- }
139- mesh . SetIndices ( indices , MeshTopology . Triangles , 0 ) ;
140- mesh . RecalculateBounds ( ) ;
141- }
142-
143- if ( handMeshData . uvs . IsCreated && handMeshData . uvs . Length == mesh . vertexCount )
144- {
145- mesh . SetUVs ( 0 , handMeshData . uvs ) ;
146- }
147- else
148- {
149- mesh . uv = null ;
150- }
151-
152- if ( handMeshData . normals . IsCreated && handMeshData . normals . Length == mesh . vertexCount )
153- {
154- mesh . SetNormals ( handMeshData . normals ) ;
155- }
156- else
157- {
158- mesh . RecalculateNormals ( ) ;
159- }
160-
161- if ( handMeshData . TryGetRootPose ( out Pose rootPose ) )
162- {
163- transform . SetWorldPose ( PlayspaceUtilities . TransformPose ( rootPose ) ) ;
164- }
165- }
133+ return ;
166134 }
167135#if MROPENXR_PRESENT && ( UNITY_STANDALONE_WIN || UNITY_WSA || UNITY_ANDROID )
168136 else if ( handMeshTracker ! = null
@@ -183,19 +151,79 @@ protected void Update()
183151 }
184152
185153 transform . SetWorldPose ( PlayspaceUtilities . TransformPose ( pose ) ) ;
154+ UpdateHandMaterial ( ) ;
155+ return ;
186156 }
187157#endif
188- else
158+
159+ // Hide the hand if we weren't able to obtain a valid mesh
160+ handRenderer . enabled = false ;
161+ }
162+
163+ private void OnHandsUpdated ( XRHandSubsystem subsystem , XRHandSubsystem . UpdateSuccessFlags successFlags , XRHandSubsystem . UpdateType updateType )
164+ {
165+ // Only update visualization on OnBeforeRender for the most accurate data
166+ if ( updateType == XRHandSubsystem . UpdateType . Dynamic ) { return ; }
167+
168+ XRHandMeshDataQueryParams queryParams = new ( )
169+ {
170+ allocator = Unity . Collections . Allocator . Temp ,
171+ } ;
172+
173+ if ( lastUpdatedFrame != Time . frameCount && ! subsystem . TryGetMeshData ( out result , ref queryParams ) )
189174 {
190- // Hide the hand and abort if we shouldn't be
191- // showing the hand, for whatever reason.
192- // (Missing joint data, no subsystem, additive
193- // display, etc!)
194- handRenderer . enabled = false ;
195175 return ;
196176 }
197177
198- UpdateHandMaterial ( ) ;
178+ if ( ( successFlags & updateSuccessFlags ) != 0 )
179+ {
180+ lastUpdatedFrame = Time . frameCount ;
181+ XRHandMeshData handMeshData = HandNode == XRNode . LeftHand ? result . leftHand : result . rightHand ;
182+ handRenderer . enabled = true ;
183+ Mesh mesh = meshFilter . mesh ;
184+
185+ if ( handMeshData . positions . Length > 0 && handMeshData . indices . Length > 0 )
186+ {
187+ mesh . SetVertices ( handMeshData . positions ) ;
188+ Unity . Collections . NativeArray < int > indices = handMeshData . indices ;
189+ // This API appears to return CCW triangles, but Unity expects CW triangles
190+ for ( int i = 0 ; i < indices . Length ; i += 3 )
191+ {
192+ ( indices [ i + 1 ] , indices [ i + 2 ] ) = ( indices [ i + 2 ] , indices [ i + 1 ] ) ;
193+ }
194+ mesh . SetIndices ( indices , MeshTopology . Triangles , 0 ) ;
195+ mesh . RecalculateBounds ( ) ;
196+ }
197+
198+ if ( handMeshData . uvs . IsCreated && handMeshData . uvs . Length == mesh . vertexCount )
199+ {
200+ mesh . SetUVs ( 0 , handMeshData . uvs ) ;
201+ }
202+ else
203+ {
204+ mesh . uv = null ;
205+ }
206+
207+ if ( handMeshData . normals . IsCreated && handMeshData . normals . Length == mesh . vertexCount )
208+ {
209+ mesh . SetNormals ( handMeshData . normals ) ;
210+ }
211+ else
212+ {
213+ mesh . RecalculateNormals ( ) ;
214+ }
215+
216+ if ( handMeshData . TryGetRootPose ( out Pose rootPose ) )
217+ {
218+ transform . SetWorldPose ( PlayspaceUtilities . TransformPose ( rootPose ) ) ;
219+ }
220+
221+ UpdateHandMaterial ( ) ;
222+ return ;
223+ }
224+
225+ // Hide the hand if we weren't able to obtain a valid mesh
226+ handRenderer . enabled = false ;
199227 }
200228
201229 protected override bool ShouldRenderHand ( )
0 commit comments