HeadHandRayPose.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. using System;
  2. using Rokid.UXR.Utility;
  3. using UnityEngine;
  4. using UnityEngine.EventSystems;
  5. namespace Rokid.UXR.Interaction
  6. {
  7. /// <summary>
  8. /// Processing the pose information of the ray
  9. /// </summary>
  10. public class HeadHandRayPose : BaseRayPose, IHeadHandDriver
  11. {
  12. private RayInteractor rayInteractor;
  13. [SerializeField]
  14. private HandType handType;
  15. [SerializeField, Tooltip("Shoulder position, symmetrically based on neck space")]
  16. private Vector3 shoulder = new Vector3(-0.2f, -0.1f, 0);
  17. [SerializeField, Tooltip("Neck position estimation, calculated based on camera space.")]
  18. private Vector3 neck = new Vector3(0, -0.1f, -0.1f);
  19. [SerializeField, Tooltip("The strength of the influence of palm direction on the ray direction.")]
  20. private float palmForwardInfluencePow = 0f;
  21. [SerializeField, Tooltip("The intensity of ray upward bending.")]
  22. private float upForwardInfluencePow = 0.0f;
  23. private Vector3 shoulderPos;
  24. private Vector3 delta = Vector3.zero;
  25. private bool rayFirstShow = true;
  26. private InteractorType interactorType = InteractorType.Far;
  27. /// <summary>
  28. /// 颈部位置的tsf
  29. /// </summary>
  30. private Transform neckTsf;
  31. private Vector3 preWirstPos = Vector3.zero;
  32. private float preCamRotY = 0;
  33. private Transform rayOrigin;
  34. private Vector3 startRayPos;
  35. private Vector3 startRayForward;
  36. private Vector3 preRayPos;
  37. private Vector3 preRayForward;
  38. private Vector3 deltaRayPos;
  39. private Vector3 deltaRayForward;
  40. private Vector3 allDeltaRayPos;
  41. private Vector3 allDeltaRayForward;
  42. private int handFrame = 0;
  43. private int headFrame = 0;
  44. private float noHoverCursorDistance;
  45. protected override void Start()
  46. {
  47. base.Start();
  48. if (rayInteractor == null)
  49. {
  50. rayInteractor = GetComponent<RayInteractor>();
  51. }
  52. GesEventInput.OnRayPoseUpdate += OnRayPoseUpdate;
  53. neckTsf = new GameObject("neck").transform;
  54. neckTsf.SetParent(transform);
  55. rayOrigin = rayInteractor.GetRayOriginTsf();
  56. noHoverCursorDistance = rayInteractor.NoHoverCursorDistance;
  57. }
  58. private void OnDestroy()
  59. {
  60. GesEventInput.OnRayPoseUpdate -= OnRayPoseUpdate;
  61. }
  62. public void OnChangeHoldHandType(HandType hand)
  63. {
  64. if (hand != HandType.None)
  65. {
  66. handType = hand;
  67. shoulder = handType == HandType.RightHand ? new Vector3(0.2f, -0.1f, 0) : new Vector3(-0.2f, 0.1f, 0);
  68. startRayPos = rayOrigin.position;
  69. startRayForward = rayOrigin.forward;
  70. }
  71. }
  72. public void OnHandPress(HandType hand)
  73. {
  74. if (handFrame > 10)
  75. {
  76. allDeltaRayPos += deltaRayPos;
  77. allDeltaRayForward += deltaRayForward;
  78. rayOrigin.rotation = Quaternion.Slerp(rayOrigin.rotation, Quaternion.FromToRotation(Vector3.forward, startRayForward + allDeltaRayForward), Time.deltaTime * 10);
  79. rayOrigin.position = Vector3.Lerp(rayOrigin.position, startRayPos + allDeltaRayPos, Time.deltaTime * 30);
  80. }
  81. }
  82. public void OnHandRelease()
  83. {
  84. headFrame++;
  85. if (Utils.IsAndroidPlatfrom() && headFrame > 1)
  86. {
  87. rayOrigin.SetPositionAndRotation(MainCameraCache.mainCamera.transform.position + new Vector3(0, 0.05f, 0), Quaternion.FromToRotation(Vector3.forward, MainCameraCache.mainCamera.transform.forward + new Vector3(0, 0.05f, 0)));
  88. }
  89. }
  90. private void OnRayPoseUpdate(HandType hand, Vector3 wrist, Vector3 handCenter, Vector3 pinchCenterOri, Vector3 pinchCenter)
  91. {
  92. if (Utils.IsUnityEditor())
  93. return;
  94. if (hand == handType)
  95. {
  96. float deltaWrist = Vector3.SqrMagnitude(wrist - preWirstPos);
  97. float deltaCamPos = Vector3.SqrMagnitude(MainCameraCache.mainCamera.transform.position - preWirstPos);
  98. neckTsf.position = MainCameraCache.mainCamera.transform.TransformPoint(neck);
  99. neckTsf.rotation = Quaternion.Euler(0, deltaWrist > 0.1f ? MainCameraCache.mainCamera.transform.eulerAngles.y : preCamRotY, 0);
  100. shoulderPos = neckTsf.TransformPoint(shoulder);
  101. preWirstPos = wrist;
  102. preCamRotY = MainCameraCache.mainCamera.transform.eulerAngles.y;
  103. //胳膊朝向
  104. Vector3 armForward = (wrist - shoulderPos).normalized;
  105. //手腕朝向
  106. Vector3 palmForWard = (handCenter - wrist).normalized;
  107. Vector3 curForward = armForward + palmForWard * palmForwardInfluencePow + Vector3.up * upForwardInfluencePow;
  108. Vector3 curPos = pinchCenterOri;
  109. deltaRayForward = curForward - preRayForward;
  110. deltaRayPos = curPos - preRayPos;
  111. preRayForward = curForward;
  112. preRayPos = curPos;
  113. handFrame++;
  114. }
  115. }
  116. public void OnBeforeChangeHoldHandType(HandType hand)
  117. {
  118. if (hand == HandType.None)
  119. {
  120. rayInteractor.NoHoverCursorDistance = noHoverCursorDistance;
  121. handType = HandType.None;
  122. allDeltaRayForward = Vector3.zero;
  123. allDeltaRayPos = Vector3.zero;
  124. handFrame = 0;
  125. headFrame = 0;
  126. }
  127. }
  128. }
  129. }