XRSupport.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. #if UNITY_INPUT_SYSTEM_ENABLE_XR || PACKAGE_DOCS_GENERATION
  2. using System;
  3. using System.Collections.Generic;
  4. using UnityEngine.XR;
  5. using UnityEngine.InputSystem.Layouts;
  6. using UnityEngine.InputSystem.Controls;
  7. using UnityEngine.Scripting;
  8. namespace UnityEngine.InputSystem.XR
  9. {
  10. /// <summary>
  11. /// A set of static utilities for registering XR Input Devices externally.
  12. /// </summary>
  13. public static class XRUtilities
  14. {
  15. /// <summary>
  16. /// A simple Regex pattern that allows InputDeviceMatchers to match to any version of the XRInput interface.
  17. /// </summary>
  18. public const string InterfaceMatchAnyVersion = "^(XRInput)";
  19. /// <summary>
  20. /// The initial, now deprecated interface for XRInput. This version handles button packing for Android differently from current.
  21. /// </summary>
  22. public const string InterfaceV1 = "XRInput";
  23. /// <summary>
  24. /// The current interface code sent with devices to identify as XRInput devices.
  25. /// </summary>
  26. public const string InterfaceCurrent = "XRInputV1";
  27. }
  28. // Sync to UnityXRInputFeatureType in IUnityXRInput.h
  29. /// <summary>
  30. /// The type of data a <see cref="XRFeatureDescriptor>"/> exposes.
  31. /// </summary>
  32. public enum FeatureType
  33. {
  34. Custom = 0,
  35. Binary,
  36. DiscreteStates,
  37. Axis1D,
  38. Axis2D,
  39. Axis3D,
  40. Rotation,
  41. Hand,
  42. Bone,
  43. Eyes
  44. }
  45. /// <summary>
  46. /// Contextual strings that identify the contextual, cross-platform use that a feature represents. <see cref="UnityEngine.XR.CommonUsages"/> for a list of unity's built-in shared usages.
  47. /// </summary>
  48. #pragma warning disable 0649
  49. [Serializable]
  50. public struct UsageHint
  51. {
  52. public string content;
  53. }
  54. //Sync to XRInputFeatureDefinition in XRInputDeviceDefinition.h
  55. /// <summary>
  56. /// Describes an individual input on a device, such as a trackpad, or button, or trigger.
  57. /// </summary>
  58. [Serializable]
  59. public struct XRFeatureDescriptor
  60. {
  61. /// <summary>
  62. /// The name of the feature.
  63. /// </summary>
  64. public string name;
  65. /// <summary>
  66. /// The uses that this feature should represent, such as trigger, or grip, or touchpad.
  67. /// </summary>
  68. public List<UsageHint> usageHints;
  69. /// <summary>
  70. /// The type of data this feature exposes.
  71. /// </summary>
  72. public FeatureType featureType;
  73. /// <summary>
  74. /// The overall size of the feature. This is only filled in when the <see cref="XRFeatureDescriptor.featureType"/> is <see cref="FeatureType.Custom"/>.
  75. /// </summary>
  76. public uint customSize;
  77. }
  78. //Sync to XRInputDeviceDefinition in XRInputDeviceDefinition.h
  79. /// <summary>
  80. /// Describes an input device: what it can do and how it should be used. These are reported during device connection, and help identify devices and map input data to the right controls.
  81. /// </summary>
  82. [Serializable]
  83. public class XRDeviceDescriptor
  84. {
  85. /// <summary>
  86. /// The name of the device.
  87. /// </summary>
  88. public string deviceName;
  89. /// <summary>
  90. /// The manufacturer of the device.
  91. /// </summary>
  92. public string manufacturer;
  93. /// <summary>
  94. /// The serial number of the device. An empty string if no serial number is available.
  95. /// </summary>
  96. public string serialNumber;
  97. #if UNITY_2019_3_OR_NEWER
  98. /// <summary>
  99. /// The capabilities of the device, used to help filter and identify devices that server a certain purpose (e.g. controller, or headset, or hardware tracker).
  100. /// </summary>
  101. public InputDeviceCharacteristics characteristics;
  102. #else //UNITY_2019_3_OR_NEWER
  103. /// <summary>
  104. /// The role of the device, used to help filter and identify devices that server a certain purpose (e.g. controller, or headset, or hardware tracker).
  105. /// </summary>
  106. public InputDeviceRole deviceRole;
  107. #endif //UNITY_2019_3_OR_NEWER
  108. /// <summary>
  109. /// The underlying deviceId, this can be used with <see cref="UnityEngine.XR.InputDevices"/> to create a device.
  110. /// </summary>
  111. public int deviceId;
  112. /// <summary>
  113. /// A list of all input features. <seealso cref="XRFeatureDescriptor"/>
  114. /// </summary>
  115. public List<XRFeatureDescriptor> inputFeatures;
  116. /// <summary>
  117. /// Converts this structure to a JSON string.
  118. /// </summary>
  119. /// <returns></returns>
  120. public string ToJson()
  121. {
  122. return JsonUtility.ToJson(this);
  123. }
  124. /// <summary>
  125. /// Converts a json string to a new <see cref="XRDeviceDescriptor"/>.
  126. /// </summary>
  127. /// <param name="json">The JSON string containing <see cref="XRDeviceDescriptor"/> data.</param>
  128. /// <returns>A new <see cref="XRDeviceDescriptor"/></returns>
  129. public static XRDeviceDescriptor FromJson(string json)
  130. {
  131. return JsonUtility.FromJson<XRDeviceDescriptor>(json);
  132. }
  133. }
  134. /// <summary>
  135. /// Represents a 3 dimensional, tracked bone within a hierarchy of other bones.
  136. /// </summary>
  137. public struct Bone
  138. {
  139. /// <summary>
  140. /// The index with the device's controls array where the parent bone resides.
  141. /// </summary>
  142. public uint parentBoneIndex { get; set; }
  143. /// <summary>
  144. /// The tracked position of the bone.
  145. /// </summary>
  146. public Vector3 position { get; set; }
  147. /// <summary>
  148. /// The tracked rotation of the bone.
  149. /// </summary>
  150. public Quaternion rotation { get; set; }
  151. }
  152. /// <summary>
  153. /// Represents a pair of tracked eyes.
  154. /// </summary>
  155. public struct Eyes
  156. {
  157. /// <summary>
  158. /// The tracked position of the left eye.
  159. /// </summary>
  160. public Vector3 leftEyePosition { get; set; }
  161. /// <summary>
  162. /// The tracked rotation of the left eye.
  163. /// </summary>
  164. public Quaternion leftEyeRotation { get; set; }
  165. /// <summary>
  166. /// The tracked position of the right eye.
  167. /// </summary>
  168. public Vector3 rightEyePosition { get; set; }
  169. /// <summary>
  170. /// The tracked rotation of the right eye.
  171. /// </summary>
  172. public Quaternion rightEyeRotation { get; set; }
  173. /// <summary>
  174. /// The point in 3D space that the pair of eyes is looking.
  175. /// </summary>
  176. public Vector3 fixationPoint { get; set; }
  177. /// <summary>
  178. /// The amount [0-1] the left eye is open or closed. 1.0 is fully open.
  179. /// </summary>
  180. public float leftEyeOpenAmount { get; set; }
  181. /// <summary>
  182. /// The amount [0-1] the right eye is open or closed. 1.0 is fully open.
  183. /// </summary>
  184. public float rightEyeOpenAmount { get; set; }
  185. }
  186. [Preserve]
  187. public class BoneControl : InputControl<Bone>
  188. {
  189. [Preserve]
  190. [InputControl(offset = 0, displayName = "parentBoneIndex")]
  191. public IntegerControl parentBoneIndex { get; private set; }
  192. [Preserve]
  193. [InputControl(offset = 4, displayName = "Position")]
  194. public Vector3Control position { get; private set; }
  195. [Preserve]
  196. [InputControl(offset = 16, displayName = "Rotation")]
  197. public QuaternionControl rotation { get; private set; }
  198. protected override void FinishSetup()
  199. {
  200. parentBoneIndex = GetChildControl<IntegerControl>("parentBoneIndex");
  201. position = GetChildControl<Vector3Control>("position");
  202. rotation = GetChildControl<QuaternionControl>("rotation");
  203. base.FinishSetup();
  204. }
  205. public override unsafe Bone ReadUnprocessedValueFromState(void* statePtr)
  206. {
  207. return new Bone()
  208. {
  209. parentBoneIndex = (uint)parentBoneIndex.ReadUnprocessedValueFromState(statePtr),
  210. position = position.ReadUnprocessedValueFromState(statePtr),
  211. rotation = rotation.ReadUnprocessedValueFromState(statePtr)
  212. };
  213. }
  214. public override unsafe void WriteValueIntoState(Bone value, void* statePtr)
  215. {
  216. parentBoneIndex.WriteValueIntoState((int)value.parentBoneIndex, statePtr);
  217. position.WriteValueIntoState(value.position, statePtr);
  218. rotation.WriteValueIntoState(value.rotation, statePtr);
  219. }
  220. }
  221. [Preserve]
  222. public class EyesControl : InputControl<Eyes>
  223. {
  224. [Preserve]
  225. [InputControl(offset = 0, displayName = "LeftEyePosition")]
  226. public Vector3Control leftEyePosition { get; private set; }
  227. [Preserve]
  228. [InputControl(offset = 12, displayName = "LeftEyeRotation")]
  229. public QuaternionControl leftEyeRotation { get; private set; }
  230. [Preserve]
  231. [InputControl(offset = 28, displayName = "RightEyePosition")]
  232. public Vector3Control rightEyePosition { get; private set; }
  233. [Preserve]
  234. [InputControl(offset = 40, displayName = "RightEyeRotation")]
  235. public QuaternionControl rightEyeRotation { get; private set; }
  236. [Preserve]
  237. [InputControl(offset = 56, displayName = "FixationPoint")]
  238. public Vector3Control fixationPoint { get; private set; }
  239. [Preserve]
  240. [InputControl(offset = 68, displayName = "LeftEyeOpenAmount")]
  241. public AxisControl leftEyeOpenAmount { get; private set; }
  242. [Preserve]
  243. [InputControl(offset = 72, displayName = "RightEyeOpenAmount")]
  244. public AxisControl rightEyeOpenAmount { get; private set; }
  245. protected override void FinishSetup()
  246. {
  247. leftEyePosition = GetChildControl<Vector3Control>("leftEyePosition");
  248. leftEyeRotation = GetChildControl<QuaternionControl>("leftEyeRotation");
  249. rightEyePosition = GetChildControl<Vector3Control>("rightEyePosition");
  250. rightEyeRotation = GetChildControl<QuaternionControl>("rightEyeRotation");
  251. fixationPoint = GetChildControl<Vector3Control>("fixationPoint");
  252. leftEyeOpenAmount = GetChildControl<AxisControl>("leftEyeOpenAmount");
  253. rightEyeOpenAmount = GetChildControl<AxisControl>("rightEyeOpenAmount");
  254. base.FinishSetup();
  255. }
  256. public override unsafe Eyes ReadUnprocessedValueFromState(void* statePtr)
  257. {
  258. return new Eyes()
  259. {
  260. leftEyePosition = leftEyePosition.ReadUnprocessedValueFromState(statePtr),
  261. leftEyeRotation = leftEyeRotation.ReadUnprocessedValueFromState(statePtr),
  262. rightEyePosition = rightEyePosition.ReadUnprocessedValueFromState(statePtr),
  263. rightEyeRotation = rightEyeRotation.ReadUnprocessedValueFromState(statePtr),
  264. fixationPoint = fixationPoint.ReadUnprocessedValueFromState(statePtr),
  265. leftEyeOpenAmount = leftEyeOpenAmount.ReadUnprocessedValueFromState(statePtr),
  266. rightEyeOpenAmount = rightEyeOpenAmount.ReadUnprocessedValueFromState(statePtr)
  267. };
  268. }
  269. public override unsafe void WriteValueIntoState(Eyes value, void* statePtr)
  270. {
  271. leftEyePosition.WriteValueIntoState(value.leftEyePosition, statePtr);
  272. leftEyeRotation.WriteValueIntoState(value.leftEyeRotation, statePtr);
  273. rightEyePosition.WriteValueIntoState(value.rightEyePosition, statePtr);
  274. rightEyeRotation.WriteValueIntoState(value.rightEyeRotation, statePtr);
  275. fixationPoint.WriteValueIntoState(value.fixationPoint, statePtr);
  276. leftEyeOpenAmount.WriteValueIntoState(value.leftEyeOpenAmount, statePtr);
  277. rightEyeOpenAmount.WriteValueIntoState(value.rightEyeOpenAmount, statePtr);
  278. }
  279. }
  280. #pragma warning restore 0649
  281. /// <summary>
  282. /// A small helper class to aid in initializing and registering XR devices and layout builders.
  283. /// </summary>
  284. #if UNITY_DISABLE_DEFAULT_INPUT_PLUGIN_INITIALIZATION
  285. public
  286. #else
  287. internal
  288. #endif
  289. static class XRSupport
  290. {
  291. /// <summary>
  292. /// Registers all initial templates and the generalized layout builder with the InputSystem.
  293. /// </summary>
  294. public static void Initialize()
  295. {
  296. InputSystem.RegisterLayout<BoneControl>("Bone");
  297. InputSystem.RegisterLayout<EyesControl>("Eyes");
  298. InputSystem.RegisterLayout<XRHMD>();
  299. InputSystem.RegisterLayout<XRController>();
  300. InputSystem.onFindLayoutForDevice += XRLayoutBuilder.OnFindLayoutForDevice;
  301. #if !DISABLE_BUILTIN_INPUT_SYSTEM_WINDOWSMR
  302. InputSystem.RegisterLayout<UnityEngine.XR.WindowsMR.Input.WMRHMD>(
  303. matches: new InputDeviceMatcher()
  304. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  305. .WithProduct("(Windows Mixed Reality HMD)|(Microsoft HoloLens)|(^(WindowsMR Headset))")
  306. );
  307. InputSystem.RegisterLayout<UnityEngine.XR.WindowsMR.Input.WMRSpatialController>(
  308. matches: new InputDeviceMatcher()
  309. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  310. .WithProduct(@"(^(Spatial Controller))|(^(OpenVR Controller\(WindowsMR))")
  311. );
  312. InputSystem.RegisterLayout<UnityEngine.XR.WindowsMR.Input.HololensHand>(
  313. matches: new InputDeviceMatcher()
  314. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  315. .WithProduct(@"(^(Hand -))")
  316. );
  317. #endif
  318. #if !DISABLE_BUILTIN_INPUT_SYSTEM_OCULUS
  319. InputSystem.RegisterLayout<Unity.XR.Oculus.Input.OculusHMD>(
  320. matches: new InputDeviceMatcher()
  321. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  322. .WithProduct("^(Oculus Rift)|^(Oculus Quest)|^(Oculus Go)"));
  323. InputSystem.RegisterLayout<Unity.XR.Oculus.Input.OculusTouchController>(
  324. matches: new InputDeviceMatcher()
  325. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  326. .WithProduct(@"(^(Oculus Touch Controller))|(^(Oculus Quest Controller))"));
  327. InputSystem.RegisterLayout<Unity.XR.Oculus.Input.OculusRemote>(
  328. matches: new InputDeviceMatcher()
  329. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  330. .WithProduct(@"Oculus Remote"));
  331. InputSystem.RegisterLayout<Unity.XR.Oculus.Input.OculusTrackingReference>(
  332. matches: new InputDeviceMatcher()
  333. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  334. .WithProduct(@"((Tracking Reference)|(^(Oculus Rift [a-zA-Z0-9]* \(Camera)))"));
  335. InputSystem.RegisterLayout<Unity.XR.Oculus.Input.OculusHMDExtended>(
  336. name: "GearVR",
  337. matches: new InputDeviceMatcher()
  338. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  339. .WithProduct("Oculus HMD"));
  340. InputSystem.RegisterLayout<Unity.XR.Oculus.Input.GearVRTrackedController>(
  341. matches: new InputDeviceMatcher()
  342. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  343. .WithProduct("^(Oculus Tracked Remote)"));
  344. #endif
  345. #if !DISABLE_BUILTIN_INPUT_SYSTEM_GOOGLEVR
  346. InputSystem.RegisterLayout<Unity.XR.GoogleVr.DaydreamHMD>(
  347. matches: new InputDeviceMatcher()
  348. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  349. .WithProduct("Daydream HMD"));
  350. InputSystem.RegisterLayout<Unity.XR.GoogleVr.DaydreamController>(
  351. matches: new InputDeviceMatcher()
  352. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  353. .WithProduct("^(Daydream Controller)"));
  354. #endif
  355. #if !DISABLE_BUILTIN_INPUT_SYSTEM_OPENVR
  356. InputSystem.RegisterLayout<Unity.XR.OpenVR.OpenVRHMD>(
  357. matches: new InputDeviceMatcher()
  358. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  359. .WithProduct("^(OpenVR Headset)|^(Vive Pro)")
  360. );
  361. InputSystem.RegisterLayout<Unity.XR.OpenVR.OpenVRControllerWMR>(
  362. matches: new InputDeviceMatcher()
  363. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  364. .WithProduct("^(OpenVR Controller\\(WindowsMR)")
  365. );
  366. InputSystem.RegisterLayout<Unity.XR.OpenVR.ViveWand>(
  367. matches: new InputDeviceMatcher()
  368. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  369. .WithManufacturer("HTC")
  370. .WithProduct(@"^(OpenVR Controller\(((Vive. Controller)|(VIVE. Controller)|(Vive Controller)))")
  371. );
  372. InputSystem.RegisterLayout<Unity.XR.OpenVR.OpenVROculusTouchController>(
  373. matches: new InputDeviceMatcher()
  374. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  375. .WithProduct(@"^(OpenVR Controller\(Oculus)")
  376. );
  377. InputSystem.RegisterLayout<Unity.XR.OpenVR.ViveTracker>(
  378. matches: new InputDeviceMatcher()
  379. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  380. .WithManufacturer("HTC")
  381. .WithProduct(@"^(VIVE Tracker)")
  382. );
  383. InputSystem.RegisterLayout<Unity.XR.OpenVR.HandedViveTracker>(
  384. matches: new InputDeviceMatcher()
  385. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  386. .WithManufacturer("HTC")
  387. .WithProduct(@"^(OpenVR Controller\(VIVE Tracker)")
  388. );
  389. InputSystem.RegisterLayout<Unity.XR.OpenVR.ViveLighthouse>(
  390. matches: new InputDeviceMatcher()
  391. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  392. .WithManufacturer("HTC")
  393. .WithProduct(@"^(HTC V2-XD/XE)")
  394. );
  395. #endif
  396. }
  397. }
  398. }
  399. #endif // UNITY_INPUT_SYSTEM_ENABLE_XR