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;
/////
///// 是否显示球棍手
/////
//public bool ShowHandJoint = true;
///
/// 头部坐标系所在的物体
///
public static Transform head;
///
/// 实例化出来作为所有手的根节点
///
GameObject prefab_handRoot;
Transform handRoot;
///
/// 记录了左手的所有信息,包括当前有没有捏合,有没有握持物体等等
///
public static HandInfo leftHand;
///
/// 记录了右手的所有信息,包括当前有没有捏合,有没有握持物体等等
///
public static HandInfo rightHand;
///
/// 由外部逻辑控制手的射线的方向
///
///
///
///
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();
if (Application.isEditor)
{
if (enableHandSimulatorInEditor)
{
gameObject.AddComponent();
}
}
StartCoroutine(enableHandDetecting());
//注册回调,以得到HandTrackingData的数据更新
NativeSwapManager.OnHandTrackingDataUpdated += OnHandTrackingDataUpdated;
//if (ShowHandJoint)
//{
// gameObject.AddComponent();
//}
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();
leftHand.Init(HandType.Left);
rightHand = handRoot_Right.GetComponent();
rightHand.Init(HandType.Right);
//拇指和食指之间用来触发近距离捏合的区域
GameObject prefab_TriggerBetweenDaddyAndMommyFinger = ResourcesManager.Load("Triggers/TriggerBetweenDaddyAndMommyFinger");
TriggerForPinch interactWithFingerTip_Left = Instantiate(prefab_TriggerBetweenDaddyAndMommyFinger, leftHand.root).GetComponent();
interactWithFingerTip_Left.SetUp(leftHand.root);
TriggerForPinch interactWithFingerTip_Right = Instantiate(prefab_TriggerBetweenDaddyAndMommyFinger, rightHand.root).GetComponent();
interactWithFingerTip_Right.SetUp(rightHand.root);
//手部的预触发区,用于切换近距离和远距离交互
GameObject prefab_TriggerForFarNearSwitch = ResourcesManager.Load("Triggers/TriggerForFarNearSwitch");
TriggerForFarNearSwitch triggerForFarNearSwitch_Left = Instantiate(prefab_TriggerForFarNearSwitch, leftHand.root).GetComponent();
triggerForFarNearSwitch_Left.SetUp(leftHand.root);
TriggerForFarNearSwitch triggerForFarNearSwitch_Right = Instantiate(prefab_TriggerForFarNearSwitch, rightHand.root).GetComponent();
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().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;
}
}
}
}