HandRayPose.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. using Rokid.UXR.Utility;
  2. using UnityEngine;
  3. using UnityEngine.UI;
  4. using Rokid.UXR.Native;
  5. namespace Rokid.UXR.Interaction
  6. {
  7. /// <summary>
  8. /// Processing the pose information of the ray
  9. /// </summary>
  10. public class HandRayPose : BaseRayPose
  11. {
  12. [Tooltip("手的类型")]
  13. [SerializeField]
  14. public HandType hand;
  15. [Tooltip("肩膀位置,基于脖子空间左右对称")]
  16. [SerializeField]
  17. private Vector3 shoulder = new Vector3(-0.2f, -0.1f, 0);
  18. [Tooltip("脖子位置估算,基于相机空间计算")]
  19. [SerializeField]
  20. private Vector3 neck = new Vector3(0, -0.1f, -0.1f);
  21. [Tooltip("手掌方向对射线方向影响的强度")]
  22. [SerializeField]
  23. private float palmForwardInfluencePow = 0.7f;
  24. [SerializeField]
  25. private RayInteractor rayInteractor;
  26. [SerializeField]
  27. private RayVisual rayVisual;
  28. [SerializeField]
  29. private Text logText;
  30. [SerializeField, Tooltip("是否打印日志")]
  31. private bool log = false;
  32. private float upForwardInfluencePow = 0.06f;
  33. private Vector3 shoulderPos;
  34. private Vector3 delta = Vector3.zero;
  35. private bool rayFirstShow = true;
  36. private InteractorType interactorType = InteractorType.Far;
  37. /// <summary>
  38. /// 颈部位置的tsf
  39. /// </summary>
  40. private Transform neckTsf;
  41. private Vector3 preWirstPos = Vector3.zero;
  42. private Vector3 wristPos = Vector3.zero;
  43. private float preCamRotY = 0;
  44. protected override void Start()
  45. {
  46. base.Start();
  47. neckTsf = new GameObject("neck").transform;
  48. neckTsf.SetParent(transform);
  49. GesEventInput.OnRayPoseUpdate += OnRayPoseUpdate;
  50. InteractorStateChange.OnInteractorTypeChange += OnInteractorTypeChange;
  51. upForwardInfluencePow = NativeInterface.NativeAPI.GetUpForwardInfluencePow();
  52. }
  53. private void OnInteractorTypeChange(HandType hand, InteractorType interactorType)
  54. {
  55. if (this.hand == hand)
  56. {
  57. rayFirstShow = true;
  58. this.interactorType = interactorType;
  59. }
  60. }
  61. private void OnEnable()
  62. {
  63. rayFirstShow = true;
  64. }
  65. private void OnDestroy()
  66. {
  67. GesEventInput.OnRayPoseUpdate -= OnRayPoseUpdate;
  68. InteractorStateChange.OnInteractorTypeChange -= OnInteractorTypeChange;
  69. }
  70. private void OnRayPoseUpdate(HandType hand, Vector3 wrist, Vector3 handCenter, Vector3 pinchCenterOri, Vector3 pinchCenter)
  71. {
  72. if (Utils.IsUnityEditor())
  73. return;
  74. if (this.hand == hand)
  75. {
  76. float deltaWrist = Vector3.SqrMagnitude(wrist - preWirstPos);
  77. neckTsf.position = MainCameraCache.mainCamera.transform.TransformPoint(neck);
  78. neckTsf.rotation = Quaternion.Euler(0, deltaWrist > 0.1f ? MainCameraCache.mainCamera.transform.eulerAngles.y : preCamRotY, 0);
  79. shoulderPos = neckTsf.TransformPoint(shoulder);
  80. preWirstPos = wrist;
  81. preCamRotY = MainCameraCache.mainCamera.transform.eulerAngles.y;
  82. //手势关键信息的更新
  83. delta = rayFirstShow ? pinchCenter - pinchCenterOri : Vector3.Lerp(delta, pinchCenter - pinchCenterOri, Time.deltaTime * 3);
  84. rayFirstShow = false;
  85. //胳膊朝向
  86. Vector3 armForward = (wrist - shoulderPos).normalized;
  87. //手腕朝向
  88. Vector3 palmForWard = (handCenter - wrist).normalized;
  89. this.transform.rotation = Quaternion.Slerp(this.transform.rotation, Quaternion.FromToRotation(Vector3.forward, armForward + palmForWard * palmForwardInfluencePow + Vector3.up * upForwardInfluencePow), Time.deltaTime * 10);
  90. if (float.IsNaN(this.transform.position.x) || float.IsNaN(this.transform.position.y) || float.IsNaN(this.transform.position.z) || float.IsNaN(this.transform.rotation.x) || float.IsNaN(this.transform.rotation.y) || float.IsNaN(this.transform.rotation.z) || float.IsNaN(this.transform.rotation.w))
  91. {
  92. RKLog.Error($"====HandRayPose==== Data Error {MainCameraCache.mainCamera.transform.position}cameraRot:{MainCameraCache.mainCamera.transform.rotation.eulerAngles},{wrist},{handCenter},{pinchCenterOri},{pinchCenter}");
  93. transform.position = Vector3.zero;
  94. transform.rotation = Quaternion.identity;
  95. neckTsf.position = Vector3.zero;
  96. neckTsf.rotation = Quaternion.identity;
  97. }
  98. this.transform.position = Vector3.Lerp(this.transform.position, pinchCenterOri + delta, Time.deltaTime * 20);
  99. LogHandRayInfo(wrist, handCenter);
  100. }
  101. }
  102. #region LogHandRayInfo
  103. private float logTime = 5;
  104. private float logElapsedTime = 0;
  105. private void LogHandRayInfo(Vector3 wrist, Vector3 handCenter)
  106. {
  107. logElapsedTime += Time.deltaTime;
  108. if (logElapsedTime > logTime)
  109. {
  110. logElapsedTime = 0;
  111. string logInfo = $"====HandRayPose====\n camPos:{MainCameraCache.mainCamera.transform.position},\n camRot:{MainCameraCache.mainCamera.transform.rotation.eulerAngles}\n neckPos: {neckTsf.position}\n shoulderPos: {shoulderPos}\n wristPos:{wrist}\n wristPosInCamera:{MainCameraCache.mainCamera.transform.InverseTransformPoint(wrist)}\n handPos:{handCenter} \n rayPos:{this.transform.position} \n rayPos:{this.transform.rotation.eulerAngles} \n rayRot:{this.transform.rotation.eulerAngles} ";
  112. if (logText != null)
  113. logText.text = logInfo;
  114. RKLog.KeyInfo(logInfo);
  115. }
  116. }
  117. #endregion
  118. }
  119. }