Files
adriadri6972 d3d9c5f833 upload project
2025-07-31 15:21:08 +02:00

169 lines
6.6 KiB
C#

#if UNITY_ANDROID && XR_HANDS
using System.Runtime.InteropServices;
using Unity.Collections;
using UnityEngine;
using UnityEngine.Scripting;
using UnityEngine.XR.Hands;
using UnityEngine.XR.Hands.ProviderImplementation;
namespace Unity.XR.XREAL
{
/// <summary>
/// The XREAL implementation of the
/// [XRHandSubsystem](xref:UnityEngine.XR.Hands.XRHandSubsystem).
/// </summary>
[Preserve]
public sealed class XREALHandSubSystem : XRHandSubsystem
{
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
static void Register()
{
XRHandSubsystemDescriptor.Register(new XRHandSubsystemDescriptor.Cinfo
{
id = "XREAL Hands",
providerType = typeof(XREALXRHandProvider),
subsystemTypeOverride = typeof(XREALHandSubSystem),
});
}
XRHandProviderUtility.SubsystemUpdater m_Updater;
protected override void OnCreate()
{
base.OnCreate();
m_Updater = new XRHandProviderUtility.SubsystemUpdater(this);
}
protected override void OnStart()
{
m_Updater.Start();
base.OnStart();
}
protected override void OnStop()
{
m_Updater.Stop();
base.OnStop();
}
protected override void OnDestroy()
{
m_Updater.Destroy();
m_Updater = null;
base.OnDestroy();
}
class XREALXRHandProvider : XRHandSubsystemProvider
{
public override void GetHandLayout(NativeArray<bool> handJointsInLayout)
{
handJointsInLayout[XRHandJointID.Wrist.ToIndex()] = true;
handJointsInLayout[XRHandJointID.Palm.ToIndex()] = true;
handJointsInLayout[XRHandJointID.ThumbMetacarpal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.ThumbProximal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.ThumbDistal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.ThumbTip.ToIndex()] = true;
handJointsInLayout[XRHandJointID.IndexMetacarpal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.IndexProximal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.IndexIntermediate.ToIndex()] = true;
handJointsInLayout[XRHandJointID.IndexDistal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.IndexTip.ToIndex()] = true;
handJointsInLayout[XRHandJointID.MiddleMetacarpal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.MiddleProximal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.MiddleIntermediate.ToIndex()] = true;
handJointsInLayout[XRHandJointID.MiddleDistal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.MiddleTip.ToIndex()] = true;
handJointsInLayout[XRHandJointID.RingMetacarpal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.RingProximal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.RingIntermediate.ToIndex()] = true;
handJointsInLayout[XRHandJointID.RingDistal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.RingTip.ToIndex()] = true;
handJointsInLayout[XRHandJointID.LittleMetacarpal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.LittleProximal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.LittleIntermediate.ToIndex()] = true;
handJointsInLayout[XRHandJointID.LittleDistal.ToIndex()] = true;
handJointsInLayout[XRHandJointID.LittleTip.ToIndex()] = true;
}
public override void Start()
{
}
public override void Stop()
{
}
public override void Destroy()
{
}
HandJointsPose m_HandJointsPose = new HandJointsPose();
public override UpdateSuccessFlags TryUpdateHands(UpdateType updateType, ref Pose leftHandRootPose, NativeArray<XRHandJoint> leftHandJoints, ref Pose rightHandRootPose, NativeArray<XRHandJoint> rightHandJoints)
{
UpdateSuccessFlags ret = UpdateSuccessFlags.None;
if (!XREALPlugin.UpdateHandPose())
return ret;
if (XREALPlugin.GetHandJointsPose(HandType.LeftHand, ref m_HandJointsPose))
{
if (m_HandJointsPose.isTracked)
{
leftHandRootPose = m_HandJointsPose.jointsPose[0];
for (int i = 0; i < m_HandJointsPose.jointsPose.Length; i++)
{
leftHandJoints[i] = XRHandProviderUtility.CreateJoint(Handedness.Left,
XRHandJointTrackingState.Pose,
XRHandJointIDUtility.FromIndex(i),
m_HandJointsPose.jointsPose[i]);
}
ret |= UpdateSuccessFlags.LeftHandRootPose | UpdateSuccessFlags.LeftHandJoints;
}
}
if (XREALPlugin.GetHandJointsPose(HandType.RightHand, ref m_HandJointsPose))
{
if (m_HandJointsPose.isTracked)
{
rightHandRootPose = m_HandJointsPose.jointsPose[0];
for (int i = 0; i < m_HandJointsPose.jointsPose.Length; i++)
{
rightHandJoints[i] = XRHandProviderUtility.CreateJoint(Handedness.Right,
XRHandJointTrackingState.Pose,
XRHandJointIDUtility.FromIndex(i),
m_HandJointsPose.jointsPose[i]);
}
ret |= UpdateSuccessFlags.RightHandRootPose | UpdateSuccessFlags.RightHandJoints;
}
}
return ret;
}
}
}
internal enum HandType
{
LeftHand = 0,
RightHand = 1,
}
internal struct HandJointsPose
{
public bool isTracked;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)XRHandJointID.EndMarker - 1)]
public Pose[] jointsPose;
}
public static partial class XREALPlugin
{
[DllImport(LibName)]
internal static extern bool UpdateHandPose();
[DllImport(LibName)]
internal static extern bool GetHandJointsPose(HandType handType, ref HandJointsPose handJoints);
}
}
#endif