XimmerseXRGesture.cs 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.InputSystem;
  5. using UnityEngine.InputSystem.LowLevel;
  6. using UnityEngine.InputSystem.Utilities;
  7. using UnityEngine.InputSystem.Layouts;
  8. using UnityEngine.InputSystem.Controls;
  9. using Ximmerse.XR.InputSystems.GazeAndGestureInteraction;
  10. namespace Ximmerse.XR.InputSystems
  11. {
  12. /// <summary>
  13. /// gesture state for input system to couple with input action properties system.
  14. /// </summary>
  15. public struct HandState : IInputStateTypeInfo
  16. {
  17. public FourCC format => new FourCC('X', 'M', 'G', 'T');
  18. #region Properties represents any hand
  19. [InputControl(name = "anyHandIsTracked", layout = "Button")]
  20. public bool anyHandIsTracked;
  21. /// <summary>
  22. /// 0 = left, 1 = right
  23. /// </summary>
  24. [InputControl(name = "handness", layout = "Integer")]
  25. public int handness;
  26. /// <summary>
  27. /// 0 = none, 3 (1+2) = position + rotation
  28. /// </summary>
  29. [InputControl(name = "trackingState", layout = "Integer")]
  30. public uint trackingState;
  31. /// <summary>
  32. /// Palm position
  33. /// </summary>
  34. [InputControl(name = "palmPosition", layout = "Vector3")]
  35. public Vector3 palmPosition;
  36. [InputControl(name = "gazeRayState", layout = "Integer")]
  37. public uint gazeRayState;
  38. [InputControl(name = "gazeRayOrigin", layout = "Vector3")]
  39. public Vector3 gazeRayOrigin;
  40. [InputControl(name = "gazeRayRotation", layout = "Quaternion")]
  41. public Quaternion gazeRayRotation;
  42. /// <summary>
  43. /// 手掌沿手指前向的法线
  44. /// </summary>
  45. [InputControl(name = "palmRotation", layout = "Quaternion")]
  46. public Quaternion palmRotation;
  47. [InputControl(name = "palmScale", layout = "Vector3")]
  48. public Vector3 palmScale;
  49. /// <summary>
  50. /// 掌心向上法线
  51. /// </summary>
  52. [InputControl(name = "palmNormal", layout = "Vector3")]
  53. public Vector3 palmNormal;
  54. /// <summary>
  55. /// 手势类型 : 抓取
  56. /// </summary>
  57. [InputControl(name = "isGrasp", layout = "Button")]
  58. public bool isGrasp;
  59. /// <summary>
  60. /// 手势类型 : 张开手掌
  61. /// </summary>
  62. [InputControl(name = "isOpenHand", layout = "Button")]
  63. public bool isOpenHand;
  64. /// <summary>
  65. /// 手势类型 : 握拳
  66. /// </summary>
  67. [InputControl(name = "isClosedHand", layout = "Button")]
  68. public bool isClosedHand;
  69. /// <summary>
  70. /// 手势类型 : 握拳
  71. /// </summary>
  72. [InputControl(name = "gripValue", layout = "Axis")]
  73. public float gripValue;
  74. #endregion
  75. }
  76. /// <summary>
  77. /// Hand gesture input device
  78. /// </summary>
  79. [InputControlLayout(stateType = typeof(HandState))]
  80. public class XimmerseXRGesture : InputDevice, IInputUpdateCallbackReceiver
  81. {
  82. [InputControl(name = "HandState/anyHandIsTracked")]
  83. public ButtonControl anyHandIsTracked
  84. {
  85. get; internal set;
  86. }
  87. /// <summary>
  88. /// Tracking state, the value mapped to UnityEngine.XR.InputTrackingState:
  89. /// None = 0, Position = 1, Rotation = 2,Velocity = 4,AngularVelocity = 8,
  90. /// Acceleration = 16,AngularAcceleration = 32, All = 63
  91. /// </summary>
  92. [InputControl(name = "HandState/trackingState")]
  93. public IntegerControl trackingState
  94. {
  95. get; internal set;
  96. }
  97. /// <summary>
  98. /// 0 = left, 1 = right
  99. /// </summary>
  100. [InputControl(name = "HandState/handness")]
  101. public IntegerControl handness
  102. {
  103. get; internal set;
  104. }
  105. [InputControl(name = "HandState/palmPosition")]
  106. public Vector3Control palmPosition
  107. {
  108. get; internal set;
  109. }
  110. [InputControl(name = "HandState/palmRotation")]
  111. public QuaternionControl palmRotation
  112. {
  113. get; internal set;
  114. }
  115. [InputControl(name = "HandState/palmScale")]
  116. public Vector3Control palmScale
  117. {
  118. get; internal set;
  119. }
  120. [InputControl(name = "HandState/gazeRayState")]
  121. public IntegerControl gazeRayState
  122. {
  123. get; internal set;
  124. }
  125. [InputControl(name = "HandState/gazeRayOrigin")]
  126. public Vector3Control gazeRayOrigin
  127. {
  128. get; internal set;
  129. }
  130. [InputControl(name = "HandState/gazeRayRotation")]
  131. public QuaternionControl gazeRayRotation
  132. {
  133. get; internal set;
  134. }
  135. [InputControl(name = "HandState/palmNormal")]
  136. public Vector3Control palmNormal
  137. {
  138. get; internal set;
  139. }
  140. [InputControl(name = "HandState/isGrasp")]
  141. public ButtonControl isGrasp
  142. {
  143. get; internal set;
  144. }
  145. [InputControl(name = "HandState/isOpenHand")]
  146. public ButtonControl isOpenHand
  147. {
  148. get; internal set;
  149. }
  150. [InputControl(name = "HandState/isClosedHand")]
  151. public ButtonControl isClosedHand
  152. {
  153. get; internal set;
  154. }
  155. [InputControl(name = "HandState/gripValue")]
  156. public AxisControl gripValue
  157. {
  158. get; internal set;
  159. }
  160. /// <summary>
  161. /// The native hand track info data.
  162. /// </summary>
  163. public HandTrackingInfo handTrackInfo
  164. {
  165. get => HandTracking.HandTrackingInfo;
  166. }
  167. public XimmerseXRGesture() : base()
  168. {
  169. displayName = "Ximmerse Gesture Input Device";
  170. }
  171. protected override void FinishSetup()
  172. {
  173. base.FinishSetup();
  174. anyHandIsTracked = GetChildControl<ButtonControl>("anyHandIsTracked");
  175. handness = GetChildControl<IntegerControl>("handness");
  176. trackingState = GetChildControl<IntegerControl>("trackingState");
  177. palmPosition = GetChildControl<Vector3Control>("palmPosition");
  178. palmRotation = GetChildControl<QuaternionControl>("palmRotation");
  179. gazeRayState = GetChildControl<IntegerControl>("gazeRayState");
  180. gazeRayOrigin = GetChildControl<Vector3Control>("gazeRayOrigin");
  181. gazeRayRotation = GetChildControl<QuaternionControl>("gazeRayRotation");
  182. palmScale = GetChildControl<Vector3Control>("palmScale");
  183. palmNormal = GetChildControl<Vector3Control>("palmNormal");
  184. isGrasp = GetChildControl<ButtonControl>("isGrasp");
  185. isOpenHand = GetChildControl<ButtonControl>("isOpenHand");
  186. isClosedHand = GetChildControl<ButtonControl>("isClosedHand");
  187. gripValue = GetChildControl<AxisControl>("gripValue");
  188. }
  189. public void OnUpdate()
  190. {
  191. var _state = new HandState();
  192. GazeAndHandInteractionSystem gazeInterSys = GazeAndHandInteractionSystem.instance;
  193. var _handTrackInfo = this.handTrackInfo;
  194. _state.anyHandIsTracked = _handTrackInfo.IsValid;
  195. _state.handness = (int)_handTrackInfo.Handness;
  196. _state.trackingState = _handTrackInfo.IsValid ? 3u : 0u;
  197. _state.palmPosition = _handTrackInfo.PalmLocalPosition;
  198. _state.palmRotation = _handTrackInfo.PalmLocalRotation;
  199. GazeAndHandInteractionSystem.GetEyeReticleLocalPose(out Pose eyeReticlePose);
  200. _state.gazeRayState = 3u;
  201. _state.gazeRayOrigin = eyeReticlePose.position;
  202. _state.gazeRayRotation = eyeReticlePose.rotation;
  203. _state.palmNormal = _handTrackInfo.PalmLocalNormal;
  204. _state.palmScale = _handTrackInfo.PalmScale;
  205. //如果 gaze interaction system 存在, 采用其抛出的优化值:
  206. bool isclosepinch = _handTrackInfo.NativeGestureType == (int)TouchlessA3D.GestureType.CLOSED_PINCH;
  207. bool isclosehand = _handTrackInfo.gestureFistOpenHand == GestureType_Fist_OpenHand.Fist;
  208. if (_handTrackInfo.IsTracking)
  209. {
  210. if (isclosepinch || isclosehand)
  211. {
  212. _state.isGrasp = true;
  213. }
  214. else
  215. {
  216. _state.isGrasp = false;
  217. }
  218. _state.isOpenHand = _handTrackInfo.gestureFistOpenHand == GestureType_Fist_OpenHand.Opened;
  219. _state.isClosedHand = _handTrackInfo.gestureFistOpenHand == GestureType_Fist_OpenHand.Fist;
  220. _state.gripValue = _state.isGrasp ? 1 : 0;
  221. }
  222. else
  223. {
  224. _state.isGrasp = false;
  225. _state.isOpenHand = true;
  226. _state.isClosedHand = false;
  227. _state.gripValue = 0;
  228. }
  229. InputSystem.QueueStateEvent(this, _state);
  230. }
  231. }
  232. }