From 528fee377446af407fc34a7ac0a662bdb91202aa Mon Sep 17 00:00:00 2001 From: Shariff Faleel Date: Wed, 13 Dec 2023 14:50:06 -0800 Subject: [PATCH] Adding HandJointData --- Runtime/Tracking.meta | 8 + Runtime/Tracking/HandJointData.cs | 225 +++++++++++++++++++++++++ Runtime/Tracking/HandJointData.cs.meta | 11 ++ Runtime/ubc.ok.ovilab.HPUI.asmdef | 4 +- 4 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 Runtime/Tracking.meta create mode 100644 Runtime/Tracking/HandJointData.cs create mode 100644 Runtime/Tracking/HandJointData.cs.meta diff --git a/Runtime/Tracking.meta b/Runtime/Tracking.meta new file mode 100644 index 0000000..4972631 --- /dev/null +++ b/Runtime/Tracking.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c5420efcd478c5d4f971a34a520329ed +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Tracking/HandJointData.cs b/Runtime/Tracking/HandJointData.cs new file mode 100644 index 0000000..c9c965a --- /dev/null +++ b/Runtime/Tracking/HandJointData.cs @@ -0,0 +1,225 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.XR.Hands; + +namespace ubco.ovi.HPUI.Core +{ + /// + /// Utility class to expose joint data accessible. + /// + public class HandJointData: MonoBehaviour + { + private XRHandSubsystem handSubsystem; + private List jointDataEvents; + + #region Unity events + /// + /// See . + /// + protected void Start() + { + // Initializing all the hand joint events + for (int i = XRHandJointIDUtility.ToIndex(XRHandJointID.BeginMarker); i < XRHandJointIDUtility.ToIndex(XRHandJointID.EndMarker); i++) + { + jointDataEvents.Add(new JointDataEventHandler(XRHandJointIDUtility.FromIndex(i), Handedness.Left)); + jointDataEvents.Add(new JointDataEventHandler(XRHandJointIDUtility.FromIndex(i), Handedness.Right)); + } + } + + /// + /// See . + /// + protected void OnDisable() + { + if (handSubsystem != null) + { + handSubsystem.trackingAcquired -= OnTrackingAcquired; + handSubsystem.trackingLost -= OnTrackingLost; + handSubsystem.updatedHands -= OnUpdatedHands; + handSubsystem = null; + } + } + + /// + /// See . + /// + protected void Update() + { + if (handSubsystem != null && handSubsystem.running) + { + return; + } + + List handSubsystems = new List(); + SubsystemManager.GetSubsystems(handSubsystems); + bool foundRunningHandSubsystem = false; + for (var i = 0; i < handSubsystems.Count; ++i) + { + XRHandSubsystem handSubsystem = handSubsystems[i]; + if (handSubsystem.running) + { + UnsubscribeHandSubsystem(); + this.handSubsystem = handSubsystem; + foundRunningHandSubsystem = true; + break; + } + } + + if (!foundRunningHandSubsystem) + { + return; + } + + SubscribeHandSubsystem(); + } + #endregion + + #region event handling + /// + /// Subscribe to events on the + /// + private void SubscribeHandSubsystem() + { + if (handSubsystem == null) + return; + + handSubsystem.trackingAcquired += OnTrackingAcquired; + handSubsystem.trackingLost += OnTrackingLost; + handSubsystem.updatedHands += OnUpdatedHands; + } + + /// + /// Unsubscribe from events on the + /// + private void UnsubscribeHandSubsystem() + { + if (handSubsystem == null) + return; + + handSubsystem.trackingAcquired -= OnTrackingAcquired; + handSubsystem.trackingLost -= OnTrackingLost; + handSubsystem.updatedHands -= OnUpdatedHands; + } + + /// + /// Event callback for + /// + private void OnUpdatedHands(XRHandSubsystem subsystem, + XRHandSubsystem.UpdateSuccessFlags updateSuccessFlags, + XRHandSubsystem.UpdateType updateType) + { + switch (updateType) + { + case XRHandSubsystem.UpdateType.Dynamic: + // Update game logic that uses hand data + break; + case XRHandSubsystem.UpdateType.BeforeRender: + foreach (JointDataEventHandler handler in jointDataEvents) + { + if (handler.handedness == Handedness.Left) + { + handler.ProcessEvent(subsystem.leftHand); + } + else if (handler.handedness == Handedness.Right) + { + handler.ProcessEvent(subsystem.rightHand); + } + } + break; + } + } + + /// + /// Event callback for + /// + private void OnTrackingAcquired(XRHand hand) + { + } + + /// + /// Event callback for + /// + private void OnTrackingLost(XRHand hand) + { + } + #endregion + + #region public interface + /// + /// Subscribe to a joint on a hand + /// + public void SubscribeToJointDataEvent(Handedness handedness, XRHandJointID joinID, EventHandler callback) + { + foreach(JointDataEventHandler handler in jointDataEvents) + { + if (handler.handedness == handedness && handler.jointID == joinID) + { + handler.jointDataEventHandler += callback; + } + } + } + + /// + /// Unsubscribe to a joint on a hand + /// + public void UnsubscribeToJointDataEvent(Handedness handedness, XRHandJointID joinID, EventHandler callback) + { + foreach(JointDataEventHandler handler in jointDataEvents) + { + if (handler.handedness == handedness && handler.jointID == joinID) + { + handler.jointDataEventHandler += callback; + } + } + } + #endregion + } + + /// + /// Event args for joint data + /// + public class JointDataEventArgs: EventArgs + { + public Pose pose; + public Handedness handedness; + public XRHandJointID jointID; + + public JointDataEventArgs(Pose pose, Handedness handedness, XRHandJointID jointID) + { + this.pose = pose; + this.handedness = handedness; + this.jointID = jointID; + } + } + + /// + /// Helper to push the pose data for a joint + /// + internal class JointDataEventHandler + { + public XRHandJointID jointID; + public Handedness handedness; + public EventHandler jointDataEventHandler; + + public JointDataEventHandler(XRHandJointID jointID, Handedness handedness) + { + this.jointID = jointID; + this.handedness = handedness; + } + + public void ProcessEvent(XRHand hand) + { + EventHandler handler = jointDataEventHandler; + if (handler != null) + { + XRHandJoint joint = hand.GetJoint(jointID); + + if (joint.TryGetPose(out Pose resultingPose)) + { + handler(this, new JointDataEventArgs(resultingPose, handedness, jointID)); + } + } + } + } +} diff --git a/Runtime/Tracking/HandJointData.cs.meta b/Runtime/Tracking/HandJointData.cs.meta new file mode 100644 index 0000000..41f1012 --- /dev/null +++ b/Runtime/Tracking/HandJointData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 38299689a440c8e4fab0a65d2117c10b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/ubc.ok.ovilab.HPUI.asmdef b/Runtime/ubc.ok.ovilab.HPUI.asmdef index 0716e27..b962f08 100644 --- a/Runtime/ubc.ok.ovilab.HPUI.asmdef +++ b/Runtime/ubc.ok.ovilab.HPUI.asmdef @@ -1,7 +1,9 @@ { "name": "ubc.ok.ovilab.HPUI", "rootNamespace": "ubc.ok.ovilab.HPUI", - "references": [], + "references": [ + "Unity.XR.Hands" + ], "includePlatforms": [], "excludePlatforms": [], "allowUnsafeCode": false,