HandUtils.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. using Rokid.UXR.Interaction;
  2. using UnityEngine;
  3. using Rokid.UXR.Native;
  4. namespace Rokid.UXR.Utility
  5. {
  6. public class HandUtils
  7. {
  8. public static Quaternion[] AdjustSkeletonsRot(Vector3[] skeletons, Quaternion[] rotations, Vector3 forward, Quaternion[] skeletonsRot)
  9. {
  10. skeletonsRot[0] = Quaternion.FromToRotation(rotations[0] * forward, skeletons[9] - skeletons[0]) * rotations[0];
  11. skeletonsRot[1] = Quaternion.FromToRotation(rotations[1] * forward, skeletons[2] - skeletons[1]) * rotations[1];
  12. skeletonsRot[2] = Quaternion.FromToRotation(rotations[2] * forward, skeletons[3] - skeletons[2]) * rotations[2];
  13. skeletonsRot[3] = Quaternion.FromToRotation(rotations[3] * forward, skeletons[4] - skeletons[3]) * rotations[3];
  14. skeletonsRot[4] = Quaternion.FromToRotation(rotations[4] * forward, skeletons[4] - skeletons[3]) * rotations[4];
  15. skeletonsRot[5] = Quaternion.FromToRotation(rotations[5] * forward, skeletons[6] - skeletons[5]) * rotations[5];
  16. skeletonsRot[6] = Quaternion.FromToRotation(rotations[6] * forward, skeletons[7] - skeletons[6]) * rotations[6];
  17. skeletonsRot[7] = Quaternion.FromToRotation(rotations[7] * forward, skeletons[8] - skeletons[7]) * rotations[7];
  18. skeletonsRot[8] = Quaternion.FromToRotation(rotations[8] * forward, skeletons[8] - skeletons[7]) * rotations[8];
  19. skeletonsRot[9] = Quaternion.FromToRotation(rotations[9] * forward, skeletons[10] - skeletons[9]) * rotations[9];
  20. skeletonsRot[10] = Quaternion.FromToRotation(rotations[10] * forward, skeletons[11] - skeletons[10]) * rotations[10];
  21. skeletonsRot[11] = Quaternion.FromToRotation(rotations[11] * forward, skeletons[12] - skeletons[11]) * rotations[11];
  22. skeletonsRot[12] = Quaternion.FromToRotation(rotations[12] * forward, skeletons[12] - skeletons[11]) * rotations[12];
  23. skeletonsRot[13] = Quaternion.FromToRotation(rotations[13] * forward, skeletons[14] - skeletons[13]) * rotations[13];
  24. skeletonsRot[14] = Quaternion.FromToRotation(rotations[14] * forward, skeletons[15] - skeletons[14]) * rotations[14];
  25. skeletonsRot[15] = Quaternion.FromToRotation(rotations[15] * forward, skeletons[16] - skeletons[15]) * rotations[15];
  26. skeletonsRot[16] = Quaternion.FromToRotation(rotations[16] * forward, skeletons[16] - skeletons[15]) * rotations[16];
  27. skeletonsRot[17] = Quaternion.FromToRotation(rotations[17] * forward, skeletons[18] - skeletons[17]) * rotations[17];
  28. skeletonsRot[18] = Quaternion.FromToRotation(rotations[18] * forward, skeletons[19] - skeletons[18]) * rotations[18];
  29. skeletonsRot[19] = Quaternion.FromToRotation(rotations[19] * forward, skeletons[20] - skeletons[19]) * rotations[19];
  30. skeletonsRot[20] = Quaternion.FromToRotation(rotations[20] * forward, skeletons[20] - skeletons[19]) * rotations[20];
  31. return skeletonsRot;
  32. }
  33. #region AdjustSkeletonPosition
  34. static float wrist_middle_cmp_dis = 0.099f;
  35. static float index_mcp_pip_dis = 0.0302203f;
  36. static float middle_mcp_pip_dis = 0.03317486f;
  37. static float ring_mcp_pip_dis = 0.02867948f;
  38. static float pinky_mcp_pip_dis = 0.02232722f;
  39. static float index_dip_pip_dis = 0.01864309f;
  40. static float middle_dip_pip_dis = 0.02395519f;
  41. static float ring_dip_pip_dis = 0.02499392f;
  42. static float pinky_dip_pip_dis = 0.02014625f;
  43. static float index_dip_tip_dis = 0.02287725f;
  44. static float middle_dip_tip_dis = 0.02539373f;
  45. static float ring_dip_tip_dis = 0.02466991f;
  46. static float pinky_dip_tip_dis = 0.01812316f;
  47. static float[] boneDis = new float[] {
  48. wrist_middle_cmp_dis,
  49. index_mcp_pip_dis,
  50. middle_mcp_pip_dis,
  51. ring_mcp_pip_dis,
  52. pinky_mcp_pip_dis,
  53. index_dip_pip_dis,
  54. middle_dip_pip_dis,
  55. ring_dip_pip_dis,
  56. pinky_dip_pip_dis,
  57. index_dip_tip_dis,
  58. middle_dip_tip_dis,
  59. ring_dip_tip_dis,
  60. pinky_dip_tip_dis
  61. };
  62. public static Vector3[] AdjustSkeletonsPos(Vector3[] skeletons, Vector3[] skeletonsPos)
  63. {
  64. int fingerMcpDisIndex = 1, fingerPipDisIndex = 5, fingerTipDisIndex = 9;
  65. for (int i = 0; i < 21; i++)
  66. {
  67. skeletonsPos[i] = skeletons[i];
  68. //调整MCP
  69. if (i == 5 || i == 9 || i == 13 || i == 17)
  70. {
  71. Vector3 direct = Vector3.Normalize(skeletons[i + 1] - skeletons[i]);
  72. skeletonsPos[i] = skeletons[i + 1] - direct * boneDis[fingerMcpDisIndex];
  73. fingerMcpDisIndex++;
  74. }
  75. //调整Pip
  76. if (i == 7 || i == 11 || i == 15 || i == 19)
  77. {
  78. Vector3 direct = Vector3.Normalize(skeletons[i] - skeletons[i - 1]);
  79. skeletonsPos[i] = skeletons[i - 1] + direct * boneDis[fingerPipDisIndex];
  80. fingerPipDisIndex++;
  81. }
  82. //调整Tip
  83. if (i == 8 || i == 12 || i == 16 || i == 20)
  84. {
  85. Vector3 direct = Vector3.Normalize(skeletons[i] - skeletons[i - 1]);
  86. skeletonsPos[i] = skeletons[i - 1] + direct * boneDis[fingerTipDisIndex];
  87. fingerTipDisIndex++;
  88. }
  89. //调整Wrist
  90. if (i == 0)
  91. {
  92. Vector3 direct = Vector3.Normalize(skeletons[9] - skeletons[0]);
  93. skeletonsPos[0] = skeletons[9] - direct * boneDis[0];
  94. }
  95. }
  96. return skeletonsPos;
  97. }
  98. #endregion
  99. private static Quaternion rotation = Quaternion.identity;
  100. public static Quaternion GetQuaternion(float[] data, bool isRight, Pose cameraPose)
  101. {
  102. rotation[0] = data[0];
  103. rotation[1] = -data[1];
  104. rotation[2] = data[2];
  105. rotation[3] = -data[3];
  106. if (isRight == false)
  107. {
  108. rotation = cameraPose.rotation * rotation * Quaternion.Euler(new Vector3(-90, 0, -90));
  109. }
  110. else
  111. {
  112. rotation = cameraPose.rotation * rotation * Quaternion.Euler(new Vector3(-90, 90, 0));
  113. }
  114. return rotation;
  115. }
  116. public static Quaternion GetQuaternion(float[] data)
  117. {
  118. return new Quaternion(data[0], data[1], data[2], data[3]);
  119. }
  120. public static Vector3 GetVector3(float[] data)
  121. {
  122. return new Vector3(data[0], data[1], data[2]);
  123. }
  124. public static Vector3[] GetVertor3Arr(float[] data, Pose cameraPose)
  125. {
  126. Vector3[] vertices = new Vector3[data.Length / 3];
  127. Vector3 vert = Vector3.zero;
  128. for (int i = 0; i < vertices.Length; i++)
  129. {
  130. vert[0] = data[3 * i] / 1000.0f;
  131. vert[1] = -data[3 * i + 1] / 1000.0f;
  132. vert[2] = data[3 * i + 2] / 1000.0f;
  133. vertices[i] = cameraPose.rotation * vert;
  134. vertices[i] += cameraPose.position;
  135. }
  136. return vertices;
  137. }
  138. public static Vector3[] GetVertor3Arr(float[][] data, Pose cameraPose)
  139. {
  140. Vector3[] vertices = new Vector3[data.Length];
  141. Vector3 vert = Vector3.zero;
  142. for (int i = 0; i < data.Length; i++)
  143. {
  144. vert[0] = data[i][0] / 1000.0f;
  145. vert[1] = -data[i][1] / 1000.0f;
  146. vert[2] = data[i][2] / 1000.0f;
  147. vertices[i] = cameraPose.rotation * vert;
  148. vertices[i] += cameraPose.position;
  149. }
  150. return vertices;
  151. }
  152. private static Matrix4x4 rightHandMatrix = Matrix4x4.identity;
  153. private static Quaternion leftHandRotation = Quaternion.identity;
  154. public static Quaternion[] GetSkeletonsQuaternion(float[] data, bool isRight, Quaternion[] rotations, Pose cameraPose)
  155. {
  156. for (int i = 0; i < 21; i++)
  157. {
  158. for (int j = 0; j < 3; j++)
  159. {
  160. rightHandMatrix.SetRow(j, new Vector3(data[9 * i + 3 * j], data[9 * i + 3 * j + 1], data[9 * i + 3 * j + 2]));
  161. }
  162. //右->左
  163. leftHandRotation[0] = rightHandMatrix.rotation[0];
  164. leftHandRotation[1] = -rightHandMatrix.rotation[1];
  165. leftHandRotation[2] = rightHandMatrix.rotation[2];
  166. leftHandRotation[3] = -rightHandMatrix.rotation[3];
  167. //左手坐标系中的空间和坐标轴转换
  168. if (isRight == false)
  169. {
  170. //左手
  171. leftHandRotation = cameraPose.rotation * leftHandRotation * Quaternion.Euler(new Vector3(-90, 0, -90));
  172. }
  173. else
  174. {
  175. //右手
  176. leftHandRotation = cameraPose.rotation * leftHandRotation * Quaternion.Euler(new Vector3(-90, 90, 0));
  177. }
  178. rotations[i] = leftHandRotation;
  179. }
  180. return rotations;
  181. }
  182. public static bool UnPinchForDistance(Vector3 indexTip, Vector3 thumbTip, float unPinchDistance)
  183. {
  184. return Vector3.Distance(indexTip, thumbTip) > unPinchDistance;
  185. }
  186. public static bool CanReleseHandDrag(HandType handType)
  187. {
  188. if (Utils.IsAndroidPlatfrom())
  189. {
  190. Vector3 indexPos = GesEventInput.Instance.GetSkeletonPose(SkeletonIndexFlag.INDEX_FINGER_TIP, handType).position;
  191. Vector3 thumbPos = GesEventInput.Instance.GetSkeletonPose(SkeletonIndexFlag.THUMB_TIP, handType).position;
  192. return HandUtils.UnPinchForDistance(indexPos, thumbPos, 0.04f) && GesEventInput.Instance.GetGestureType(handType) != GestureType.Grip;
  193. }
  194. else
  195. {
  196. return Input.GetMouseButtonUp(0);
  197. }
  198. }
  199. public static Vector3 InverseTransformPoint(Pose pose, Vector3 point)
  200. {
  201. return Quaternion.Inverse(pose.rotation) * (point - pose.position);
  202. }
  203. public static Vector3 TransformPoint(Pose pose, Vector3 point)
  204. {
  205. return pose.rotation * point + pose.position;
  206. }
  207. }
  208. }