Handspårning – MRTK2
Profil för handspårning
Handspårningsprofilen finns under profilen Indatasystem. Den innehåller inställningar för att anpassa handrepresentation.
Gemensamma prefabs
Gemensamma prefabs visualiseras med hjälp av enkla prefabs. Handflatan och Pekfinger lederna är av särskild betydelse och har sin egen prefab, medan alla andra leder delar samma prefab.
Som standard är handledsprefaberna enkla geometriska primitiver. Dessa kan ersättas om du vill. Om ingen prefab anges alls skapas tomma GameObjects i stället.
Varning
Undvik att använda komplexa skript eller dyr rendering i gemensamma prefab, eftersom gemensamma objekt transformeras på varje ram och kan ha betydande prestandakostnader!
Standardhandledsrepresentation | Gemensamma etiketter |
---|---|
Handnätsprefab
Handnätet används om fullständigt definierade nätdata tillhandahålls av handspårningsenheten. Det nät som kan renderas i prefab ersätts av data från enheten, så det räcker med ett dummynät som t.ex. en kub. Materialet i prefab används för handnätet.
Handnätsvisning kan ha en märkbar prestandapåverkan, av den anledningen kan den inaktiveras helt genom att avmarkera alternativet Aktivera visualisering av handnät .
Inställningar för handvisualisering
Handnäts- och handfogningsvisualiseringarna kan stängas av eller aktiveras via inställningen Visualiseringslägen för handnät respektive handsammansättningslägen . De här inställningarna är specifika för programläge, vilket innebär att det är möjligt att aktivera vissa funktioner i redigeraren (till exempel för att se joints med simulering i redigeringsprogrammet) samtidigt som samma funktioner inaktiveras när de distribueras till enheten (i spelarversioner).
Observera att det vanligtvis rekommenderas att handledsvisualiseringen är aktiverad i redigeraren (så att simulering i redigeraren visar var handfogarna finns) och att både handledvisualisering och handnätvisualisering inaktiveras i spelaren (eftersom de ådrar sig en prestandaträff).
Skript
Position och rotation kan begäras från indatasystemet för varje enskild handfog som en MixedRealityPose
.
Alternativt tillåter systemet åtkomst till GameObjects som följer lederna. Detta kan vara användbart om en annan GameObject ska spåra en joint kontinuerligt.
Tillgängliga leder listas i TrackedHandJoint
uppräkningen.
Anteckning
Gemensamma föremål förstörs när handspårning går förlorad! Se till att alla skript som använder det gemensamma objektet hanterar ärendet null
på ett smidigt sätt för att undvika fel!
Åtkomst till en viss handkontrollant
En specifik handkontrollant är ofta tillgänglig, t.ex. vid hantering av indatahändelser. I det här fallet kan gemensamma data begäras direkt från enheten med hjälp av IMixedRealityHand
gränssnittet.
Avsökning av gemensam pose från kontrollant
Funktionen TryGetJoint
returnerar false
om den begärda jointen inte är tillgänglig av någon anledning. I så fall blir MixedRealityPose.ZeroIdentity
den resulterande posen .
public void OnSourceDetected(SourceStateEventData eventData)
{
var hand = eventData.Controller as IMixedRealityHand;
if (hand != null)
{
if (hand.TryGetJoint(TrackedHandJoint.IndexTip, out MixedRealityPose jointPose)
{
// ...
}
}
}
Gemensam transformering från handvisualisering
Gemensamma objekt kan begäras från kontrollantvisualiseraren.
public void OnSourceDetected(SourceStateEventData eventData)
{
var handVisualizer = eventData.Controller.Visualizer as IMixedRealityHandVisualizer;
if (handVisualizer != null)
{
if (handVisualizer.TryGetJointTransform(TrackedHandJoint.IndexTip, out Transform jointTransform)
{
// ...
}
}
}
Förenklad gemensam dataåtkomst
Om ingen specifik kontrollant ges tillhandahålls verktygsklasser för bekväm åtkomst till gemensamma handdata. Dessa funktioner begär gemensamma data från den första tillgängliga handenheten som för närvarande spåras.
Avsökning av gemensam pose från HandJointUtils
HandJointUtils
är en statisk klass som frågar den första aktiva handenheten.
if (HandJointUtils.TryGetJointPose(TrackedHandJoint.IndexTip, Handedness.Right, out MixedRealityPose pose))
{
// ...
}
Gemensam transformering från handledstjänst
IMixedRealityHandJointService
behåller en beständig uppsättning GameObjects för spårningsfogar.
var handJointService = CoreServices.GetInputSystemDataProvider<IMixedRealityHandJointService>();
if (handJointService != null)
{
Transform jointTransform = handJointService.RequestJointTransform(TrackedHandJoint.IndexTip, Handedness.Right);
// ...
}
Handspårningshändelser
Indatasystemet tillhandahåller även händelser, om det inte är önskvärt att avsöka data direkt från kontrollanter.
Gemensamma händelser
IMixedRealityHandJointHandler
hanterar uppdateringar av gemensamma positioner.
public class MyHandJointEventHandler : IMixedRealityHandJointHandler
{
public Handedness myHandedness;
void IMixedRealityHandJointHandler.OnHandJointsUpdated(InputEventData<IDictionary<TrackedHandJoint, MixedRealityPose>> eventData)
{
if (eventData.Handedness == myHandedness)
{
if (eventData.InputData.TryGetValue(TrackedHandJoint.IndexTip, out MixedRealityPose pose))
{
// ...
}
}
}
}
Mesh-händelser
IMixedRealityHandMeshHandler
hanterar ändringar i det ledade handnätet.
Observera att handnät inte är aktiverade som standard.
public class MyHandMeshEventHandler : IMixedRealityHandMeshHandler
{
public Handedness myHandedness;
public Mesh myMesh;
public void OnHandMeshUpdated(InputEventData<HandMeshInfo> eventData)
{
if (eventData.Handedness == myHandedness)
{
myMesh.vertices = eventData.InputData.vertices;
myMesh.normals = eventData.InputData.normals;
myMesh.triangles = eventData.InputData.triangles;
if (eventData.InputData.uvs != null && eventData.InputData.uvs.Length > 0)
{
myMesh.uv = eventData.InputData.uvs;
}
// ...
}
}
}
Kända problem
.NET Native
Det finns för närvarande ett känt problem med huvudversioner med hjälp av .NET-serverdelen. I .NET Native IInspectable
kan pekare inte konverteras från intern till hanterad kod med hjälp av Marshal.GetObjectForIUnknown
. MRTK använder detta för att hämta SpatialCoordinateSystem
för att ta emot hand- och ögondata från plattformen.
Vi har angett DLL-källan som en lösning på det här problemet i den interna Mixed Reality Toolkit-lagringsplatsen. Följ anvisningarna i README där och kopiera de resulterande binärfilerna till en plugin-mapp i Dina Unity-tillgångar. Därefter löser skriptet WindowsMixedRealityUtilities som tillhandahålls i MRTK lösningen åt dig.
Om du vill skapa en egen DLL eller ta med den här lösningen i en befintlig, är lösningens kärna:
extern "C" __declspec(dllexport) void __stdcall MarshalIInspectable(IUnknown* nativePtr, IUnknown** inspectable)
{
*inspectable = nativePtr;
}
Och dess användning i din C# Unity-kod:
[DllImport("DotNetNativeWorkaround.dll", EntryPoint = "MarshalIInspectable")]
private static extern void GetSpatialCoordinateSystem(IntPtr nativePtr, out SpatialCoordinateSystem coordinateSystem);
private static SpatialCoordinateSystem GetSpatialCoordinateSystem(IntPtr nativePtr)
{
try
{
GetSpatialCoordinateSystem(nativePtr, out SpatialCoordinateSystem coordinateSystem);
return coordinateSystem;
}
catch
{
UnityEngine.Debug.LogError("Call to the DotNetNativeWorkaround plug-in failed. The plug-in is required for correct behavior when using .NET Native compilation");
return Marshal.GetObjectForIUnknown(nativePtr) as SpatialCoordinateSystem;
}
}