GesEventInput.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. using System.Text;
  2. using System;
  3. using UnityEngine;
  4. using UnityEngine.EventSystems;
  5. using Rokid.UXR.Module;
  6. using Rokid.UXR.Utility;
  7. namespace Rokid.UXR.Interaction
  8. {
  9. #region Data
  10. /// <summary>
  11. /// Types of Gesture Interaction
  12. /// </summary>
  13. public enum InteractorType
  14. {
  15. None,
  16. //near-field interaction
  17. Near,
  18. //far-field interaction
  19. Far
  20. }
  21. /// <summary>
  22. /// Hand bone node marker index
  23. /// </summary>
  24. public enum SkeletonIndexFlag
  25. {
  26. WRIST = 0,
  27. THUMB_CMC = 1,
  28. THUMB_MCP = 2,
  29. THUMB_IP = 3,
  30. THUMB_TIP = 4,
  31. INDEX_FINGER_MCP = 5,
  32. INDEX_FINGER_PIP = 6,
  33. INDEX_FINGER_DIP = 7,
  34. INDEX_FINGER_TIP = 8,
  35. MIDDLE_FINGER_MCP = 9,
  36. MIDDLE_FINGER_PIP = 10,
  37. MIDDLE_FINGER_DIP = 11,
  38. MIDDLE_FINGER_TIP = 12,
  39. RING_FINGER_MCP = 13,
  40. RING_FINGER_PIP = 14,
  41. RING_FINGER_DIP = 15,
  42. RING_FINGER_TIP = 16,
  43. PINKY_MCP = 17,
  44. PINKY_PIP = 18,
  45. PINKY_DIP = 19,
  46. PINKY_TIP = 20
  47. }
  48. /// <summary>
  49. /// Gesture data class
  50. /// </summary>
  51. [Serializable]
  52. public class Gesture
  53. {
  54. /// <summary>
  55. /// Types of hands
  56. /// </summary>
  57. public HandType handType;
  58. /// <summary>
  59. /// Types of gestures
  60. /// </summary>
  61. public GestureType gesType;
  62. /// <summary>
  63. /// Pressed in a certain frame
  64. /// </summary>
  65. public bool handDown;
  66. /// <summary>
  67. /// Released in a certain frame
  68. /// </summary>
  69. public bool handUp;
  70. /// <summary>
  71. /// Hand is Click
  72. /// </summary>
  73. public bool handClick;
  74. /// <summary>
  75. /// Hand is Pressing
  76. /// </summary>
  77. public bool handPress;
  78. /// <summary>
  79. /// Hand is tracking succcess
  80. /// </summary>
  81. public bool trackingSuccess;
  82. /// <summary>
  83. /// Hand Center Position
  84. /// </summary>
  85. public Vector3 position;
  86. /// <summary>
  87. /// Hand delta position
  88. /// </summary>
  89. public Vector3 deltaPos;
  90. /// <summary>
  91. /// Hand orientation
  92. /// </summary>
  93. public HandOrientation handOrientation;
  94. public void Reset()
  95. {
  96. gesType = GestureType.None;
  97. handDown = false;
  98. handUp = false;
  99. handClick = false;
  100. handPress = false;
  101. }
  102. public Gesture(HandType type)
  103. {
  104. this.handType = type;
  105. }
  106. public override string ToString()
  107. {
  108. StringBuilder builder = new StringBuilder();
  109. builder.Append("HandType:").Append(handType.ToString())
  110. .Append(" GesType:").Append(gesType.ToString())
  111. .Append(" HandDown:").Append(handDown)
  112. .Append(" HandUp:").Append(handUp)
  113. .Append(" HandClick:").Append(handClick)
  114. .Append(" HandPress:").Append(handPress)
  115. .Append(" HandOrientation:").Append(handOrientation)
  116. .Append(" Position:").Append(position)
  117. .Append(" deltaPos:").Append(deltaPos);
  118. return builder.ToString();
  119. }
  120. }
  121. /// <summary>
  122. /// Types of gestures
  123. /// </summary>
  124. public enum GestureType
  125. {
  126. None = -1,
  127. Grip = 1,
  128. Palm = 2,
  129. Pinch = 3,
  130. OpenPinch = 4,
  131. }
  132. /// <summary>
  133. /// Types of hands
  134. /// </summary>
  135. public enum HandType
  136. {
  137. None = 0,
  138. LeftHand = 2,
  139. RightHand = 1
  140. }
  141. /// <summary>
  142. /// Types of handoientation
  143. /// </summary>
  144. public enum HandOrientation
  145. {
  146. None = -1,
  147. Palm = 0,
  148. Back = 1
  149. }
  150. /// <summary>
  151. /// NormalHand / HeadHand
  152. /// </summary>
  153. public enum HandOrHeadHandType
  154. {
  155. NormalHand,
  156. HeadHand
  157. }
  158. #endregion
  159. /// <summary>
  160. /// Gesture event input, provide all gesture external interface
  161. /// </summary>
  162. public class GesEventInput : MonoSingleton<GesEventInput>, IEventInput
  163. {
  164. #region Event
  165. /// <summary>
  166. /// Hand click callback
  167. /// </summary>
  168. /// <typeparam HandType >Hand type</typeparam>
  169. public static Action<HandType> OnGesClick;
  170. /// <summary>
  171. /// hand press callback
  172. /// </summary>
  173. /// <typeparam HandType >Hand type</typeparam>
  174. public static Action<HandType> OnHandPress;
  175. /// <summary>
  176. /// Hand release callback
  177. /// </summary>
  178. /// <typeparam HandType >Hand type</typeparam>
  179. public static Action<HandType> OnHandRelease;
  180. /// <summary>
  181. /// Gesture tracked failed callback
  182. /// </summary>
  183. /// <typeparam HandType >handtype=leftHand lefthand lost, handtype=rightHand righthand lost</typeparam>
  184. public static Action<HandType> OnTrackedFailed;
  185. /// <summary>
  186. /// Hand track success callback update invoke
  187. /// </summary>
  188. /// <typeparam HandType >hand type</typeparam>
  189. public static Action<HandType> OnTrackedSuccess;
  190. /// <summary>
  191. /// Process Gesture Data
  192. /// </summary>
  193. /// <typeparam GestureResults >The result of the gesture data returned </typeparam>
  194. public static Action<HandType, GestureBean> OnProcessGesData;
  195. /// <summary>
  196. /// Use log ges fps
  197. /// </summary>
  198. /// <typeparam Vector3 >wrist pos</typeparam>
  199. public static Action<float> OnGesDataUpdate;
  200. /// <summary>
  201. /// Use to proceess ges log
  202. /// </summary>
  203. /// <typeparam float >The time difference between the upper and lower frames of the gesture</typeparam>
  204. public static Action<string> OnLogGesData;
  205. /// <summary>
  206. /// Use to process ray pose
  207. /// </summary>
  208. /// <typeparam HandType >Hand type lefthand/righthand</typeparam>
  209. /// <typeparam Vector3 >Wrist pos</typeparam>
  210. /// <typeparam Vector3 >Handcenter pos</typeparam>
  211. /// <typeparam Vector3 >Pinchcenter base pos</typeparam>
  212. /// <typeparam Vector3 >Pinchcenter pos</typeparam>
  213. public static Action<HandType, Vector3, Vector3, Vector3, Vector3> OnRayPoseUpdate;
  214. /// <summary>
  215. /// Use to render hand update invoke
  216. /// </summary>
  217. /// <typeparam HandType >hand type</typeparam>
  218. public static Action<HandType, GestureBean> OnRenderHand;
  219. /// <summary>
  220. /// On handlost in camera space callback
  221. /// </summary>
  222. /// <typeparam HandType >hand type</typeparam>
  223. public static Action<HandType> OnHandLostInCameraSpace;
  224. /// <summary>
  225. /// On hand orientaion change callback update invoke
  226. /// </summary>
  227. public static Action<HandType, HandOrientation> OnHandOrientationUpdate;
  228. /// <summary>
  229. /// Gesture module action callback
  230. /// </summary>
  231. public static Action OnActiveGesModule;
  232. /// <summary>
  233. /// Gesture module release callback
  234. /// </summary>
  235. public static Action OnReleaseGesModule;
  236. /// <summary>
  237. /// Gesture module init callback
  238. /// </summary>
  239. public static Action OnInitialzeGesModule;
  240. /// <summary>
  241. /// Hand or headhand type change callback
  242. /// </summary>
  243. public static Action<HandOrHeadHandType> OnHandOrHeadHandTypeChange;
  244. #endregion
  245. [SerializeField]
  246. private GesImplementation gesInput;
  247. /// <summary>
  248. /// Interator
  249. /// </summary>
  250. /// <value></value>
  251. public Transform Interactor { get; set; }
  252. /// <summary>
  253. /// Auto change headhand or handtype
  254. /// </summary>
  255. /// <value></value>
  256. public bool autoChangeHeadHandOrHandType = false;
  257. private bool initialize = false;
  258. private GesImplementation GesInput
  259. {
  260. get
  261. {
  262. if (gesInput == null)
  263. {
  264. if (gameObject.GetComponent<GesImplementation>() != null)
  265. {
  266. gesInput = gameObject.GetComponent<GesImplementation>();
  267. }
  268. else
  269. {
  270. gesInput = gameObject.AddComponent<GesImplementation>();
  271. }
  272. }
  273. return gesInput;
  274. }
  275. }
  276. /// <summary>
  277. /// Gesture Module Initialize
  278. /// </summary>
  279. /// <param name="parent">Generates the parent of the interactor</param>
  280. public void Initialize(Transform parent)
  281. {
  282. if (Utils.IsAndroidPlatfrom() && !FuncDeviceCheck.CheckHandTrackingFunc())
  283. {
  284. return;
  285. }
  286. #if UNITY_EDITOR
  287. if (GetComponent<GestureMockInEditor>() == null)
  288. gameObject.AddComponent<GestureMockInEditor>();
  289. #endif
  290. if (Interactor == null)
  291. {
  292. GameObject go = GameObject.Find("RKHand");
  293. if (go == null)
  294. {
  295. go = GameObject.Instantiate(Resources.Load<GameObject>("Prefabs/Interactor/RKHand"));
  296. }
  297. go.name = "RKHand";
  298. Interactor = go.transform;
  299. Interactor.SetParent(transform);
  300. }
  301. Interactor.SetParent(transform);
  302. if (parent != null)
  303. this.transform.SetParent(parent);
  304. OnInitialzeGesModule?.Invoke();
  305. ActiveHandOrHeadHand(HandOrHeadHandType.NormalHand);
  306. GesInput.Initialze();
  307. initialize = true;
  308. RKLog.KeyInfo("====GesEventInit==== Init");
  309. }
  310. /// <summary>
  311. /// Activate hand interaction or head-hand interaction
  312. /// </summary>
  313. /// <param name="handOrHeadHandType"></param>
  314. public void ActiveHandOrHeadHand(HandOrHeadHandType handOrHeadHandType)
  315. {
  316. OnHandOrHeadHandTypeChange?.Invoke(handOrHeadHandType);
  317. }
  318. /// <summary>
  319. /// Release Gesture
  320. /// </summary>
  321. public void Release()
  322. {
  323. OnReleaseGesModule?.Invoke();
  324. Destroy(this.gameObject);
  325. }
  326. /// <summary>
  327. /// OnDestroy
  328. /// </summary>
  329. protected override void OnDestroy()
  330. {
  331. OnGesClick = null;
  332. OnTrackedFailed = null;
  333. OnHandPress = null;
  334. OnHandRelease = null;
  335. OnTrackedSuccess = null;
  336. OnProcessGesData = null;
  337. OnGesDataUpdate = null;
  338. OnLogGesData = null;
  339. OnRenderHand = null;
  340. initialize = false;
  341. }
  342. /// <summary>
  343. /// Active Gesture
  344. /// </summary>
  345. public void ActiveModule()
  346. {
  347. RKLog.KeyInfo("====GesEventInput==== : ActiveModule");
  348. OnActiveGesModule?.Invoke();
  349. RKVirtualController.Instance.Change(ControllerType.NORMAL);
  350. RKVirtualController.Instance.UseCustomGamePadEvent(false);
  351. EventSystem.current.pixelDragThreshold = 60;
  352. }
  353. /// <summary>
  354. /// Get Hand Pose
  355. /// </summary>
  356. /// <param name="hand">handtype lefthand righthand</param>
  357. /// <returns></returns>
  358. public Vector3 GetHandDeltaPos(HandType hand)
  359. {
  360. if (!initialize) { return Vector3.zero; };
  361. return GesInput.GetHandDeltaPos(hand);
  362. }
  363. /// <summary>
  364. /// GetHandDown
  365. /// </summary>
  366. /// <param name="type">left/right hand</param>
  367. /// <param name="isPinch">true pinch / false grip</param>
  368. /// <returns></returns>
  369. public bool GetHandDown(HandType type, bool isPinch)
  370. {
  371. if (!initialize) { return false; };
  372. return GesInput.GetHandDown(type, isPinch);
  373. }
  374. /// <summary>
  375. /// Get Hand Up
  376. /// </summary>
  377. /// <param name="type">left/right hand</param>
  378. /// <param name="isPinch">true pinch / false grip</param>
  379. /// <returns>When hand up return true or return false </returns>
  380. public bool GetHandUp(HandType type, bool isPinch)
  381. {
  382. if (!initialize) { return false; };
  383. return GesInput.GetHandUp(type, isPinch);
  384. }
  385. /// <summary>
  386. /// Get Hand Press
  387. /// </summary>
  388. /// <param name="type">left/right hand</param>
  389. /// <param name="isPinch">true pinch / false grip</param>
  390. /// <returns>When hand press return true or return false </returns>
  391. public bool GetHandPress(HandType type, bool isPinch)
  392. {
  393. if (!initialize) { return false; };
  394. return GesInput.GetHandPress(type, isPinch);
  395. }
  396. /// <summary>
  397. /// Get hand down
  398. /// </summary>
  399. /// <param name="type">left/right hand</param>
  400. /// <returns></returns>
  401. public bool GetHandDown(HandType type)
  402. {
  403. if (!initialize) { return false; };
  404. return GesInput.GetHandDown(type);
  405. }
  406. /// <summary>
  407. /// Get hand press
  408. /// </summary>
  409. /// <param name="type">left/right hand</param>
  410. /// <returns></returns>
  411. public bool GetHandPress(HandType type)
  412. {
  413. if (!initialize) { return false; };
  414. return GesInput.GetHandPress(type);
  415. }
  416. /// <summary>
  417. /// Set user height default 170 cm
  418. /// </summary>
  419. /// <param name="height"></param>
  420. public void SetUserHeight(float height)
  421. {
  422. if (!initialize) { return; };
  423. gesInput.SetUserHeight(height);
  424. }
  425. /// <summary>
  426. /// Get hand up
  427. /// </summary>
  428. /// <param name="type">left/right hand</param>
  429. /// <returns></returns>
  430. public bool GetHandUp(HandType type)
  431. {
  432. if (!initialize) { return false; };
  433. return GesInput.GetHandUp(type);
  434. }
  435. /// <summary>
  436. /// Get current gesture info
  437. /// </summary>
  438. /// <param name="type">left/right hand</param>
  439. /// <returns></returns>
  440. public Gesture GetGesture(HandType type)
  441. {
  442. if (!initialize) { return default(Gesture); };
  443. return GesInput.GetGesture(type);
  444. }
  445. /// <summary>
  446. /// Get current gesture type
  447. /// </summary>
  448. /// <param name="type">left/right hand</param>
  449. /// <returns></returns>
  450. public GestureType GetGestureType(HandType type)
  451. {
  452. if (!initialize) { return GestureType.None; };
  453. return GesInput.GetGestureType(type);
  454. }
  455. /// <summary>
  456. /// Get current hand center position
  457. /// </summary>
  458. /// <param name="type">left/right hand</param>
  459. /// <returns></returns>
  460. public Vector3 GetHandPos(HandType handType)
  461. {
  462. if (!initialize) { return Vector3.zero; };
  463. return GesInput.GetHandPos(handType);
  464. }
  465. /// <summary>
  466. /// Get current hand pose
  467. /// </summary>
  468. /// <param name="type">left/right hand</param>
  469. /// <returns>hand pose </returns>
  470. public Pose GetHandPose(HandType handType)
  471. {
  472. if (!initialize) { return Pose.identity; };
  473. return GesInput.GetHandPose(handType);
  474. }
  475. /// <summary>
  476. /// Get Skeleton Pose
  477. /// </summary>
  478. /// <param name="flag">Seleton index flag</param>
  479. /// <param name="type">left/right hand</param>
  480. /// <returns></returns>
  481. public Pose GetSkeletonPose(SkeletonIndexFlag flag, HandType type)
  482. {
  483. if (!initialize) { return Pose.identity; };
  484. return GesInput.GetSkeletonPose(flag, type);
  485. }
  486. /// <summary>
  487. /// Get hand interactor type
  488. /// </summary>
  489. /// <param name="type">left/right hand</param>
  490. /// <returns>InteractorType Near/Far </returns>
  491. public InteractorType GetInteractorType(HandType hand)
  492. {
  493. if (!initialize) { return InteractorType.None; };
  494. return GesInput.GetInteractorType(hand);
  495. }
  496. /// <summary>
  497. /// Set interacor type
  498. /// </summary>
  499. /// <param name="type">InteractorType Near/Far</param>
  500. /// <param name="hand">left/right hand</param>
  501. public void SetInteractorType(InteractorType type, HandType hand)
  502. {
  503. if (!initialize) { return; };
  504. GesInput.SetInteractorType(type, hand);
  505. }
  506. /// <summary>
  507. /// Get hand orientation
  508. /// </summary>
  509. /// <param name="hand">left/right hand</param>
  510. /// <returns></returns>
  511. public HandOrientation GetHandOrientation(HandType hand)
  512. {
  513. if (!initialize) { return HandOrientation.None; };
  514. return GesInput.GetHandOrientation(hand);
  515. }
  516. /// <summary>
  517. /// Unity Update
  518. /// </summary>
  519. private void Update()
  520. {
  521. if (!initialize)
  522. return;
  523. #if UNITY_EDITOR
  524. if (Input.GetKeyDown(KeyCode.G) || Input.GetKeyDown(KeyCode.F))
  525. {
  526. this.ActiveModule();
  527. }
  528. if (Input.GetKeyDown(KeyCode.O))
  529. {
  530. ActiveHandOrHeadHand(HandOrHeadHandType.HeadHand);
  531. }
  532. if (Input.GetKeyDown(KeyCode.I))
  533. {
  534. ActiveHandOrHeadHand(HandOrHeadHandType.NormalHand);
  535. }
  536. #else
  537. if (GetHandDown(HandType.LeftHand) &&
  538. GetHandOrientation(HandType.LeftHand) == HandOrientation.Palm)
  539. {
  540. ProcessActiveModule(HandType.LeftHand);
  541. if (autoChangeHeadHandOrHandType)
  542. ActiveHandOrHeadHand(HandOrHeadHandType.HeadHand);
  543. }
  544. if (GetHandDown(HandType.RightHand) &&
  545. GetHandOrientation(HandType.RightHand) == HandOrientation.Palm)
  546. {
  547. ProcessActiveModule(HandType.RightHand);
  548. if (autoChangeHeadHandOrHandType)
  549. ActiveHandOrHeadHand(HandOrHeadHandType.NormalHand);
  550. }
  551. #endif
  552. }
  553. /// <summary>
  554. /// Process module active logic
  555. /// </summary>
  556. /// <param name="hand">left/right hand</param>
  557. private void ProcessActiveModule(HandType hand)
  558. {
  559. Vector3 handPos = GesEventInput.Instance.GetHandPose(hand).position;
  560. Vector3 camereSpaceHandPos = MainCameraCache.mainCamera.transform.InverseTransformPoint(handPos);
  561. float hFov = Vector3.Angle(Vector3.forward, new Vector3(camereSpaceHandPos.x, 0, camereSpaceHandPos.z));
  562. float vFov = Vector3.Angle(Vector3.forward, new Vector3(0, camereSpaceHandPos.y, camereSpaceHandPos.z));
  563. // RKLog.Debug($"====GesEventInput==== hFov:{hFov}, vFov:{vFov}");
  564. if (hFov < 30 && vFov < 20)
  565. {
  566. this.ActiveModule();
  567. }
  568. }
  569. }
  570. }