123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- using EZXR.Glass.Core;
- using EZXR.Glass.Simulator.Hand;
- using EZXR.Glass.SixDof;
- using System.Collections;
- using UnityEngine;
- namespace EZXR.Glass.Inputs
- {
- [ScriptExecutionOrder(-49)]
- public class ARHandManager : MonoBehaviour
- {
- #region singleton
- private static ARHandManager instance;
- public static ARHandManager Instance
- {
- get
- {
- return instance;
- }
- }
- #endregion
- public enum HandTrackingMode
- {
- HighPrecision,//GPU
- HighEfficiency,//DSP
- }
- HandTrackingMode handTrackingMode = HandTrackingMode.HighPrecision;
- public bool enableHandSimulatorInEditor = true;
- ///// <summary>
- ///// 是否显示球棍手
- ///// </summary>
- //public bool ShowHandJoint = true;
- /// <summary>
- /// 头部坐标系所在的物体
- /// </summary>
- public static Transform head;
- /// <summary>
- /// 实例化出来作为所有手的根节点
- /// </summary>
- GameObject prefab_handRoot;
- Transform handRoot;
- /// <summary>
- /// 记录了左手的所有信息,包括当前有没有捏合,有没有握持物体等等
- /// </summary>
- public static HandInfo leftHand;
- /// <summary>
- /// 记录了右手的所有信息,包括当前有没有捏合,有没有握持物体等等
- /// </summary>
- public static HandInfo rightHand;
- /// <summary>
- /// 由外部逻辑控制手的射线的方向
- /// </summary>
- /// <param name="handInfo"></param>
- /// <param name="rayDir"></param>
- /// <returns></returns>
- public delegate bool Delegate_SetRayDataByExternal(HandInfo handInfo, ref Vector3 value);
- public static Delegate_SetRayDataByExternal SetRayDirByExternal;
- public static Delegate_SetRayDataByExternal SetRayStartPointByExternal;
- private void Awake()
- {
- instance = this;
- gameObject.AddComponent<NativeSwapManager>();
- if (Application.isEditor)
- {
- if (enableHandSimulatorInEditor)
- {
- gameObject.AddComponent<HandSimulator>();
- }
- }
- StartCoroutine(enableHandDetecting());
- //注册回调,以得到HandTrackingData的数据更新
- NativeSwapManager.OnHandTrackingDataUpdated += OnHandTrackingDataUpdated;
- //if (ShowHandJoint)
- //{
- // gameObject.AddComponent<HandsVisualization>();
- //}
- head = HMDPoseTracker.Instance.Head;
- Transform handRoot_Left = transform.Find("Left");
- Transform handRoot_Right = transform.Find("Right");
- #region 兼容旧版
- if (handRoot_Left == null || handRoot_Right == null)
- {
- handRoot = transform.Find("HandRoot");
- handRoot_Left = handRoot.Find("HandRoot_Left");
- handRoot_Right = handRoot.Find("HandRoot_Right");
- }
- #endregion
- //初始化HandInfo,以指定HandInfo是左手还是右手
- leftHand = handRoot_Left.GetComponent<HandInfo>();
- leftHand.Init(HandType.Left);
- rightHand = handRoot_Right.GetComponent<HandInfo>();
- rightHand.Init(HandType.Right);
- //拇指和食指之间用来触发近距离捏合的区域
- GameObject prefab_TriggerBetweenDaddyAndMommyFinger = ResourcesManager.Load<GameObject>("Triggers/TriggerBetweenDaddyAndMommyFinger");
- TriggerForPinch interactWithFingerTip_Left = Instantiate(prefab_TriggerBetweenDaddyAndMommyFinger, leftHand.root).GetComponent<TriggerForPinch>();
- interactWithFingerTip_Left.SetUp(leftHand.root);
- TriggerForPinch interactWithFingerTip_Right = Instantiate(prefab_TriggerBetweenDaddyAndMommyFinger, rightHand.root).GetComponent<TriggerForPinch>();
- interactWithFingerTip_Right.SetUp(rightHand.root);
- //手部的预触发区,用于切换近距离和远距离交互
- GameObject prefab_TriggerForFarNearSwitch = ResourcesManager.Load<GameObject>("Triggers/TriggerForFarNearSwitch");
- TriggerForFarNearSwitch triggerForFarNearSwitch_Left = Instantiate(prefab_TriggerForFarNearSwitch, leftHand.root).GetComponent<TriggerForFarNearSwitch>();
- triggerForFarNearSwitch_Left.SetUp(leftHand.root);
- TriggerForFarNearSwitch triggerForFarNearSwitch_Right = Instantiate(prefab_TriggerForFarNearSwitch, rightHand.root).GetComponent<TriggerForFarNearSwitch>();
- triggerForFarNearSwitch_Right.SetUp(rightHand.root);
- }
- private void OnApplicationPause(bool pause)
- {
- if (!pause)
- {
- if (!Application.isEditor)
- {
- StartCoroutine(enableHandDetecting());
- }
- }
- }
- private void OnDestroy()
- {
- disableHandDetecting();
- }
- public void changeHandRunMode(HandTrackingMode mode)
- {
- handTrackingMode = mode;
- StartCoroutine(enableHandDetecting());
- }
- // 控制器统一管理时,激活手势功能
- public void SetActive(bool value)
- {
- //StartCoroutine(enableHandDetecting());
- //transform.GetComponent<NativeSwapManager>().enabled = true;
- //for (int i = 0; i < transform.childCount; i++)
- //{
- // transform.GetChild(i).gameObject.SetActive(true);
- //}
- gameObject.SetActive(value);
- }
- private IEnumerator resetHandRunMode(HandTrackingMode mode)
- {
- yield return new WaitUntil(() => SessionManager.Instance != null && SessionManager.Instance.IsInited);
- NativeSwapManager.setHandRunMode((int)handTrackingMode);
- }
- private IEnumerator enableHandDetecting()
- {
- yield return new WaitUntil(() => SessionManager.Instance != null && SessionManager.Instance.IsInited);
- if (handTrackingMode == HandTrackingMode.HighEfficiency)
- {
- SessionManager.Instance.ARInitConfig.HandsFindingMode = HandsFindingMode.Enable_HighEfficiency;
- }
- else if (handTrackingMode == HandTrackingMode.HighPrecision)
- {
- SessionManager.Instance.ARInitConfig.HandsFindingMode = HandsFindingMode.Enable_HighPrecision;
- }
- SessionManager.Instance.ResumeSession();
- }
- private void disableHandDetecting()
- {
- SessionManager.Instance.ARInitConfig.HandsFindingMode = HandsFindingMode.Disable;
- SessionManager.Instance.ResumeSession();
- }
- public void UpdateHandTrackingDataManually(NativeSwapManager.HandTrackingData[] handTrackingData)
- {
- OnHandTrackingDataUpdated(handTrackingData);
- }
- private void OnHandTrackingDataUpdated(NativeSwapManager.HandTrackingData[] handTrackingData)
- {
- NativeSwapManager.HandTrackingData handTrackingData_Left, handTrackingData_Right;
- handTrackingData_Left = handTrackingData[0];
- handTrackingData_Right = handTrackingData[1];
- //开启或关闭虚拟手物体(直接关闭手GameObject的原因是当手不存在的时候不应该执行任何逻辑)
- leftHand.root.gameObject.SetActive(handTrackingData_Left.isTracked);
- rightHand.root.gameObject.SetActive(handTrackingData_Right.isTracked);
- //刷新手的数据
- leftHand.UpdateHandInfoData(handTrackingData_Left);
- rightHand.UpdateHandInfoData(handTrackingData_Right);
- }
- public HandInfo GetHand(HandType handedness)
- {
- if (handedness == HandType.Left)
- {
- return leftHand;
- }
- else
- {
- return rightHand;
- }
- }
- }
- }
|