Skip to content

Commit 3bf5e41

Browse files
committed
Move to event handler?
1 parent 027cb81 commit 3bf5e41

File tree

1 file changed

+85
-57
lines changed

1 file changed

+85
-57
lines changed

org.mixedrealitytoolkit.input/Visualizers/PlatformHandVisualizer/PlatformHandMeshVisualizer.cs

Lines changed: 85 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)