HandDriver.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. using System.Collections.Generic;
  2. using TouchSocket.Core;
  3. using UnityEngine;
  4. public class HandDriver : MonoBehaviour
  5. {
  6. public Network Network;
  7. public enum HandType
  8. {
  9. Left,
  10. Right
  11. }
  12. public int HandDeviceIndex = 1;
  13. public HandType Hand;
  14. private Dictionary<string, Quaternion> _originQuaternionDic;
  15. public Transform Thumb1;
  16. public Transform Thumb2;
  17. public Transform Thumb3;
  18. public Transform Index1;
  19. public Transform Index2;
  20. public Transform Index3;
  21. public Transform Middle1;
  22. public Transform Middle2;
  23. public Transform Middle3;
  24. public Transform Ring1;
  25. public Transform Ring2;
  26. public Transform Ring3;
  27. public Transform Pinky1;
  28. public Transform Pinky2;
  29. public Transform Pinky3;
  30. public Transform Wrist;
  31. [Header("坐标系偏差")] public int Pitch = 0;
  32. public int Roll = 0;
  33. public int Yaw = 0;
  34. [Header("IMU开关")] public bool HasIMU = false;
  35. [Header("拇指根节点系数")] [Range(0, 1)] public float coefficient = 0.6f;
  36. [Header("拇指根节点偏差")] public Vector3 Thumb1Offset;
  37. // Start is called before the first frame update
  38. void Start()
  39. {
  40. if (Network == null)
  41. {
  42. if (GameObject.Find("Network") == null)
  43. {
  44. GameObject network = new GameObject("Network");
  45. network.AddComponent<Network>();
  46. }
  47. Network = GameObject.Find("Network").GetComponent<Network>();
  48. }
  49. _originQuaternionDic = new Dictionary<string, Quaternion>();
  50. InitJoints();
  51. }
  52. private void InitJoints()
  53. {
  54. _originQuaternionDic.AddOrUpdate(Thumb1.name, Thumb1.localRotation);
  55. _originQuaternionDic.AddOrUpdate(Thumb2.name, Thumb2.localRotation);
  56. _originQuaternionDic.AddOrUpdate(Thumb3.name, Thumb3.localRotation);
  57. _originQuaternionDic.AddOrUpdate(Index1.name, Index1.localRotation);
  58. _originQuaternionDic.AddOrUpdate(Index2.name, Index2.localRotation);
  59. _originQuaternionDic.AddOrUpdate(Index3.name, Index3.localRotation);
  60. _originQuaternionDic.AddOrUpdate(Middle1.name, Middle1.localRotation);
  61. _originQuaternionDic.AddOrUpdate(Middle2.name, Middle2.localRotation);
  62. _originQuaternionDic.AddOrUpdate(Middle3.name, Middle3.localRotation);
  63. _originQuaternionDic.AddOrUpdate(Ring1.name, Ring1.localRotation);
  64. _originQuaternionDic.AddOrUpdate(Ring2.name, Ring2.localRotation);
  65. _originQuaternionDic.AddOrUpdate(Ring3.name, Ring3.localRotation);
  66. _originQuaternionDic.AddOrUpdate(Pinky1.name, Pinky1.localRotation);
  67. _originQuaternionDic.AddOrUpdate(Pinky2.name, Pinky2.localRotation);
  68. _originQuaternionDic.AddOrUpdate(Pinky3.name, Pinky3.localRotation);
  69. _originQuaternionDic.AddOrUpdate(Wrist.name, Wrist.localRotation);
  70. }
  71. private void Rotate(Transform tran, float angle, int angleType)
  72. {
  73. float angleX = 0;
  74. float angleY = 0;
  75. float angleZ = 0;
  76. switch (angleType)
  77. {
  78. case -3:
  79. angleX = -angle;
  80. break;
  81. case -2:
  82. angleY = -angle;
  83. break;
  84. case -1:
  85. angleZ = -angle;
  86. break;
  87. case 0:
  88. angleX = angle;
  89. break;
  90. case 1:
  91. angleY = angle;
  92. break;
  93. case 2:
  94. angleZ = angle;
  95. break;
  96. }
  97. tran.Rotate(angleX, angleY, angleZ);
  98. }
  99. private void ResetRotation(Transform trans)
  100. {
  101. if (_originQuaternionDic.TryGetValue(trans.name, out Quaternion rot))
  102. {
  103. trans.localRotation = rot;
  104. }
  105. }
  106. // Update is called once per frame
  107. void Update()
  108. {
  109. UpdateThumb();
  110. UpdateIndex();
  111. UpdateMiddle();
  112. UpdateRing();
  113. UpdatePinky();
  114. UpdateWrist();
  115. }
  116. private void UpdateWrist()
  117. {
  118. if (HasIMU)
  119. {
  120. // if (Hand == HandType.Left)
  121. // {
  122. // Quaternion quat_r = new Quaternion(
  123. // Network.Convert2Angle(HandDeviceIndex, "l26") + Network.ClbrationQuaternionOffset.x,
  124. // Network.Convert2Angle(HandDeviceIndex, "l25") + Network.ClbrationQuaternionOffset.y,
  125. // Network.Convert2Angle(HandDeviceIndex, "l27") + Network.ClbrationQuaternionOffset.z,
  126. // Network.Convert2Angle(HandDeviceIndex, "l24") + Network.ClbrationQuaternionOffset.w);
  127. // ResetRotation(Wrist);
  128. // Wrist.Rotate(-quat_r.eulerAngles.z, -quat_r.eulerAngles.x, -quat_r.eulerAngles.y);
  129. // }
  130. // else
  131. // {
  132. // Quaternion quat_r = new Quaternion(Network.Convert2Angle(HandDeviceIndex, "r26"),
  133. // Network.Convert2Angle(HandDeviceIndex, "r25"),
  134. // Network.Convert2Angle(HandDeviceIndex, "r27"), Network.Convert2Angle(HandDeviceIndex, "r24"));
  135. // ResetRotation(Wrist);
  136. // Wrist.Rotate(-quat_r.eulerAngles.z, -quat_r.eulerAngles.x, -quat_r.eulerAngles.y);
  137. // }
  138. }
  139. }
  140. private void UpdateThumb()
  141. {
  142. ResetRotation(Thumb1);
  143. ResetRotation(Thumb2);
  144. ResetRotation(Thumb3);
  145. if (Hand == HandType.Left)
  146. {
  147. Rotate(Thumb3, Network.Convert2Angle(HandDeviceIndex, "l0"), Pitch);
  148. Rotate(Thumb2, Network.Convert2Angle(HandDeviceIndex, "l1"), Pitch);
  149. Rotate(Thumb1, Network.Convert2Angle(HandDeviceIndex, "l2") * coefficient + Thumb1Offset.y, Pitch);
  150. Rotate(Thumb1, Network.Convert2Angle(HandDeviceIndex, "l3") + Thumb1Offset.z, Yaw);
  151. Rotate(Thumb1, Network.Convert2Angle(HandDeviceIndex, "l20") + Thumb1Offset.x, Roll);
  152. }
  153. else
  154. {
  155. Rotate(Thumb3, Network.Convert2Angle(HandDeviceIndex, "r0"), Pitch);
  156. Rotate(Thumb2, Network.Convert2Angle(HandDeviceIndex, "r1"), Pitch);
  157. Rotate(Thumb1, Network.Convert2Angle(HandDeviceIndex, "r2") * coefficient + Thumb1Offset.y, Pitch);
  158. Rotate(Thumb1, Network.Convert2Angle(HandDeviceIndex, "r3") + Thumb1Offset.z, Yaw);
  159. Rotate(Thumb1, Network.Convert2Angle(HandDeviceIndex, "r20") + Thumb1Offset.x, Roll);
  160. }
  161. }
  162. private void UpdateIndex()
  163. {
  164. ResetRotation(Index1);
  165. ResetRotation(Index2);
  166. ResetRotation(Index3);
  167. if (Hand == HandType.Left)
  168. {
  169. Rotate(Index3, Network.Convert2Angle(HandDeviceIndex, "l4"), Pitch);
  170. Rotate(Index2, Network.Convert2Angle(HandDeviceIndex, "l5"), Pitch);
  171. Rotate(Index1, Network.Convert2Angle(HandDeviceIndex, "l6"), Pitch);
  172. Rotate(Index1, Network.Convert2Angle(HandDeviceIndex, "l7"), Yaw);
  173. Rotate(Index1, Network.Convert2Angle(HandDeviceIndex, "l21"), Roll);
  174. }
  175. else
  176. {
  177. Rotate(Index3, Network.Convert2Angle(HandDeviceIndex, "r4"), Pitch);
  178. Rotate(Index2, Network.Convert2Angle(HandDeviceIndex, "r5"), Pitch);
  179. Rotate(Index1, Network.Convert2Angle(HandDeviceIndex, "r6"), Pitch);
  180. Rotate(Index1, Network.Convert2Angle(HandDeviceIndex, "r7"), Yaw);
  181. Rotate(Index1, Network.Convert2Angle(HandDeviceIndex, "r21"), Roll);
  182. }
  183. }
  184. private void UpdateMiddle()
  185. {
  186. ResetRotation(Middle1);
  187. ResetRotation(Middle2);
  188. ResetRotation(Middle3);
  189. if (Hand == HandType.Left)
  190. {
  191. Rotate(Middle3, Network.Convert2Angle(HandDeviceIndex, "l8"), Pitch);
  192. Rotate(Middle2, Network.Convert2Angle(HandDeviceIndex, "l9"), Pitch);
  193. Rotate(Middle1, Network.Convert2Angle(HandDeviceIndex, "l10"), Pitch);
  194. Rotate(Middle1, Network.Convert2Angle(HandDeviceIndex, "l11"), Yaw);
  195. }
  196. else
  197. {
  198. Rotate(Middle3, Network.Convert2Angle(HandDeviceIndex, "r8"), Pitch);
  199. Rotate(Middle2, Network.Convert2Angle(HandDeviceIndex, "r9"), Pitch);
  200. Rotate(Middle1, Network.Convert2Angle(HandDeviceIndex, "r10"), Pitch);
  201. Rotate(Middle1, Network.Convert2Angle(HandDeviceIndex, "r11"), Yaw);
  202. }
  203. }
  204. private void UpdateRing()
  205. {
  206. ResetRotation(Ring1);
  207. ResetRotation(Ring2);
  208. ResetRotation(Ring3);
  209. if (Hand == HandType.Left)
  210. {
  211. Rotate(Ring3, Network.Convert2Angle(HandDeviceIndex, "l12"), Pitch);
  212. Rotate(Ring2, Network.Convert2Angle(HandDeviceIndex, "l13"), Pitch);
  213. Rotate(Ring1, Network.Convert2Angle(HandDeviceIndex, "l14"), Pitch);
  214. Rotate(Ring1, -Network.Convert2Angle(HandDeviceIndex, "l15"), Yaw);
  215. }
  216. else
  217. {
  218. Rotate(Ring3, Network.Convert2Angle(HandDeviceIndex, "r12"), Pitch);
  219. Rotate(Ring2, Network.Convert2Angle(HandDeviceIndex, "r13"), Pitch);
  220. Rotate(Ring1, Network.Convert2Angle(HandDeviceIndex, "r14"), Pitch);
  221. Rotate(Ring1, -Network.Convert2Angle(HandDeviceIndex, "r15"), Yaw);
  222. }
  223. }
  224. private void UpdatePinky()
  225. {
  226. ResetRotation(Pinky1);
  227. ResetRotation(Pinky2);
  228. ResetRotation(Pinky3);
  229. if (Hand == HandType.Left)
  230. {
  231. Rotate(Pinky3, Network.Convert2Angle(HandDeviceIndex, "l16"), Pitch);
  232. Rotate(Pinky2, Network.Convert2Angle(HandDeviceIndex, "l17"), Pitch);
  233. Rotate(Pinky1, Network.Convert2Angle(HandDeviceIndex, "l18"), Pitch);
  234. Rotate(Pinky1, -Network.Convert2Angle(HandDeviceIndex, "l19"), Yaw);
  235. Rotate(Pinky1, -Network.Convert2Angle(HandDeviceIndex, "l22"), Roll);
  236. }
  237. else
  238. {
  239. Rotate(Pinky3, Network.Convert2Angle(HandDeviceIndex, "r16"), Pitch);
  240. Rotate(Pinky2, Network.Convert2Angle(HandDeviceIndex, "r17"), Pitch);
  241. Rotate(Pinky1, Network.Convert2Angle(HandDeviceIndex, "r18"), Pitch);
  242. Rotate(Pinky1, -Network.Convert2Angle(HandDeviceIndex, "r19"), Yaw);
  243. Rotate(Pinky1, -Network.Convert2Angle(HandDeviceIndex, "r22"), Roll);
  244. }
  245. }
  246. }