No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

XRSupport.cs 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. // ENABLE_VR is not defined on Game Core but the assembly is available with limited features when the XR module is enabled.
  2. #if UNITY_INPUT_SYSTEM_ENABLE_XR && (ENABLE_VR || UNITY_GAMECORE) || PACKAGE_DOCS_GENERATION
  3. using System;
  4. using System.Collections.Generic;
  5. using UnityEngine.InputSystem.Layouts;
  6. using UnityEngine.InputSystem.Controls;
  7. using UnityEngine.XR;
  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="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. /// <summary>
  98. /// 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).
  99. /// </summary>
  100. public InputDeviceCharacteristics characteristics;
  101. /// <summary>
  102. /// The underlying deviceId, this can be used with <see cref="UnityEngine.XR.InputDevices"/> to create a device.
  103. /// </summary>
  104. public int deviceId;
  105. /// <summary>
  106. /// A list of all input features. <seealso cref="XRFeatureDescriptor"/>
  107. /// </summary>
  108. public List<XRFeatureDescriptor> inputFeatures;
  109. /// <summary>
  110. /// Converts this structure to a JSON string.
  111. /// </summary>
  112. /// <returns></returns>
  113. public string ToJson()
  114. {
  115. return JsonUtility.ToJson(this);
  116. }
  117. /// <summary>
  118. /// Converts a json string to a new <see cref="XRDeviceDescriptor"/>.
  119. /// </summary>
  120. /// <param name="json">The JSON string containing <see cref="XRDeviceDescriptor"/> data.</param>
  121. /// <returns>A new <see cref="XRDeviceDescriptor"/></returns>
  122. public static XRDeviceDescriptor FromJson(string json)
  123. {
  124. return JsonUtility.FromJson<XRDeviceDescriptor>(json);
  125. }
  126. }
  127. /// <summary>
  128. /// Represents a 3 dimensional, tracked bone within a hierarchy of other bones.
  129. /// </summary>
  130. public struct Bone
  131. {
  132. /// <summary>
  133. /// The index with the device's controls array where the parent bone resides.
  134. /// </summary>
  135. public uint m_ParentBoneIndex;
  136. /// <summary>
  137. /// The tracked position of the bone.
  138. /// </summary>
  139. public Vector3 m_Position;
  140. /// <summary>
  141. /// The tracked rotation of the bone.
  142. /// </summary>
  143. public Quaternion m_Rotation;
  144. /// <summary>
  145. /// The index with the device's controls array where the parent bone resides.
  146. /// </summary>
  147. public uint parentBoneIndex
  148. {
  149. get => m_ParentBoneIndex;
  150. set => m_ParentBoneIndex = value;
  151. }
  152. /// <summary>
  153. /// The tracked position of the bone.
  154. /// </summary>
  155. public Vector3 position
  156. {
  157. get => m_Position;
  158. set => m_Position = value;
  159. }
  160. /// <summary>
  161. /// The tracked rotation of the bone.
  162. /// </summary>
  163. public Quaternion rotation
  164. {
  165. get => m_Rotation;
  166. set => m_Rotation = value;
  167. }
  168. }
  169. /// <summary>
  170. /// Represents a pair of tracked eyes.
  171. /// </summary>
  172. public struct Eyes
  173. {
  174. /// <summary>
  175. /// The tracked position of the left eye.
  176. /// </summary>
  177. public Vector3 m_LeftEyePosition;
  178. /// <summary>
  179. /// The tracked rotation of the left eye.
  180. /// </summary>
  181. public Quaternion m_LeftEyeRotation;
  182. /// <summary>
  183. /// The tracked position of the right eye.
  184. /// </summary>
  185. public Vector3 m_RightEyePosition;
  186. /// <summary>
  187. /// The tracked rotation of the right eye.
  188. /// </summary>
  189. public Quaternion m_RightEyeRotation;
  190. /// <summary>
  191. /// The point in 3D space that the pair of eyes is looking.
  192. /// </summary>
  193. public Vector3 m_FixationPoint;
  194. /// <summary>
  195. /// The amount [0-1] the left eye is open or closed. 1.0 is fully open.
  196. /// </summary>
  197. public float m_LeftEyeOpenAmount;
  198. /// <summary>
  199. /// The amount [0-1] the right eye is open or closed. 1.0 is fully open.
  200. /// </summary>
  201. public float m_RightEyeOpenAmount;
  202. /// <summary>
  203. /// The tracked position of the left eye.
  204. /// </summary>
  205. public Vector3 leftEyePosition
  206. {
  207. get => m_LeftEyePosition;
  208. set => m_LeftEyePosition = value;
  209. }
  210. /// <summary>
  211. /// The tracked rotation of the left eye.
  212. /// </summary>
  213. public Quaternion leftEyeRotation
  214. {
  215. get => m_LeftEyeRotation;
  216. set => m_LeftEyeRotation = value;
  217. }
  218. /// <summary>
  219. /// The tracked position of the right eye.
  220. /// </summary>
  221. public Vector3 rightEyePosition
  222. {
  223. get => m_RightEyePosition;
  224. set => m_RightEyePosition = value;
  225. }
  226. /// <summary>
  227. /// The tracked rotation of the right eye.
  228. /// </summary>
  229. public Quaternion rightEyeRotation
  230. {
  231. get => m_RightEyeRotation;
  232. set => m_RightEyeRotation = value;
  233. }
  234. /// <summary>
  235. /// The point in 3D space that the pair of eyes is looking.
  236. /// </summary>
  237. public Vector3 fixationPoint
  238. {
  239. get => m_FixationPoint;
  240. set => m_FixationPoint = value;
  241. }
  242. /// <summary>
  243. /// The amount [0-1] the left eye is open or closed. 1.0 is fully open.
  244. /// </summary>
  245. public float leftEyeOpenAmount
  246. {
  247. get => m_LeftEyeOpenAmount;
  248. set => m_LeftEyeOpenAmount = value;
  249. }
  250. /// <summary>
  251. /// The amount [0-1] the right eye is open or closed. 1.0 is fully open.
  252. /// </summary>
  253. public float rightEyeOpenAmount
  254. {
  255. get => m_RightEyeOpenAmount;
  256. set => m_RightEyeOpenAmount = value;
  257. }
  258. }
  259. public class BoneControl : InputControl<Bone>
  260. {
  261. [InputControl(offset = 0, displayName = "parentBoneIndex")]
  262. public IntegerControl parentBoneIndex { get; set; }
  263. [InputControl(offset = 4, displayName = "Position")]
  264. public Vector3Control position { get; set; }
  265. [InputControl(offset = 16, displayName = "Rotation")]
  266. public QuaternionControl rotation { get; set; }
  267. protected override void FinishSetup()
  268. {
  269. parentBoneIndex = GetChildControl<IntegerControl>("parentBoneIndex");
  270. position = GetChildControl<Vector3Control>("position");
  271. rotation = GetChildControl<QuaternionControl>("rotation");
  272. base.FinishSetup();
  273. }
  274. public override unsafe Bone ReadUnprocessedValueFromState(void* statePtr)
  275. {
  276. return new Bone()
  277. {
  278. parentBoneIndex = (uint)parentBoneIndex.ReadUnprocessedValueFromStateWithCaching(statePtr),
  279. position = position.ReadUnprocessedValueFromStateWithCaching(statePtr),
  280. rotation = rotation.ReadUnprocessedValueFromStateWithCaching(statePtr)
  281. };
  282. }
  283. public override unsafe void WriteValueIntoState(Bone value, void* statePtr)
  284. {
  285. parentBoneIndex.WriteValueIntoState((int)value.parentBoneIndex, statePtr);
  286. position.WriteValueIntoState(value.position, statePtr);
  287. rotation.WriteValueIntoState(value.rotation, statePtr);
  288. }
  289. }
  290. public class EyesControl : InputControl<Eyes>
  291. {
  292. [InputControl(offset = 0, displayName = "LeftEyePosition")]
  293. public Vector3Control leftEyePosition { get; set; }
  294. [InputControl(offset = 12, displayName = "LeftEyeRotation")]
  295. public QuaternionControl leftEyeRotation { get; set; }
  296. [InputControl(offset = 28, displayName = "RightEyePosition")]
  297. public Vector3Control rightEyePosition { get; set; }
  298. [InputControl(offset = 40, displayName = "RightEyeRotation")]
  299. public QuaternionControl rightEyeRotation { get; set; }
  300. [InputControl(offset = 56, displayName = "FixationPoint")]
  301. public Vector3Control fixationPoint { get; set; }
  302. [InputControl(offset = 68, displayName = "LeftEyeOpenAmount")]
  303. public AxisControl leftEyeOpenAmount { get; set; }
  304. [InputControl(offset = 72, displayName = "RightEyeOpenAmount")]
  305. public AxisControl rightEyeOpenAmount { get; set; }
  306. protected override void FinishSetup()
  307. {
  308. leftEyePosition = GetChildControl<Vector3Control>("leftEyePosition");
  309. leftEyeRotation = GetChildControl<QuaternionControl>("leftEyeRotation");
  310. rightEyePosition = GetChildControl<Vector3Control>("rightEyePosition");
  311. rightEyeRotation = GetChildControl<QuaternionControl>("rightEyeRotation");
  312. fixationPoint = GetChildControl<Vector3Control>("fixationPoint");
  313. leftEyeOpenAmount = GetChildControl<AxisControl>("leftEyeOpenAmount");
  314. rightEyeOpenAmount = GetChildControl<AxisControl>("rightEyeOpenAmount");
  315. base.FinishSetup();
  316. }
  317. public override unsafe Eyes ReadUnprocessedValueFromState(void* statePtr)
  318. {
  319. return new Eyes()
  320. {
  321. leftEyePosition = leftEyePosition.ReadUnprocessedValueFromStateWithCaching(statePtr),
  322. leftEyeRotation = leftEyeRotation.ReadUnprocessedValueFromStateWithCaching(statePtr),
  323. rightEyePosition = rightEyePosition.ReadUnprocessedValueFromStateWithCaching(statePtr),
  324. rightEyeRotation = rightEyeRotation.ReadUnprocessedValueFromStateWithCaching(statePtr),
  325. fixationPoint = fixationPoint.ReadUnprocessedValueFromStateWithCaching(statePtr),
  326. leftEyeOpenAmount = leftEyeOpenAmount.ReadUnprocessedValueFromStateWithCaching(statePtr),
  327. rightEyeOpenAmount = rightEyeOpenAmount.ReadUnprocessedValueFromStateWithCaching(statePtr)
  328. };
  329. }
  330. public override unsafe void WriteValueIntoState(Eyes value, void* statePtr)
  331. {
  332. leftEyePosition.WriteValueIntoState(value.leftEyePosition, statePtr);
  333. leftEyeRotation.WriteValueIntoState(value.leftEyeRotation, statePtr);
  334. rightEyePosition.WriteValueIntoState(value.rightEyePosition, statePtr);
  335. rightEyeRotation.WriteValueIntoState(value.rightEyeRotation, statePtr);
  336. fixationPoint.WriteValueIntoState(value.fixationPoint, statePtr);
  337. leftEyeOpenAmount.WriteValueIntoState(value.leftEyeOpenAmount, statePtr);
  338. rightEyeOpenAmount.WriteValueIntoState(value.rightEyeOpenAmount, statePtr);
  339. }
  340. }
  341. #pragma warning restore 0649
  342. /// <summary>
  343. /// A small helper class to aid in initializing and registering XR devices and layout builders.
  344. /// </summary>
  345. #if UNITY_DISABLE_DEFAULT_INPUT_PLUGIN_INITIALIZATION
  346. public
  347. #else
  348. internal
  349. #endif
  350. static class XRSupport
  351. {
  352. /// <summary>
  353. /// Registers all initial templates and the generalized layout builder with the InputSystem.
  354. /// </summary>
  355. public static void Initialize()
  356. {
  357. #if !UNITY_FORCE_INPUTSYSTEM_XR_OFF
  358. InputSystem.RegisterLayout<PoseControl>("Pose");
  359. InputSystem.RegisterLayout<BoneControl>("Bone");
  360. InputSystem.RegisterLayout<EyesControl>("Eyes");
  361. InputSystem.RegisterLayout<XRHMD>();
  362. InputSystem.RegisterLayout<XRController>();
  363. InputSystem.onFindLayoutForDevice += XRLayoutBuilder.OnFindLayoutForDevice;
  364. // Built-in layouts replaced by the com.unity.xr.windowsmr package.
  365. #if !DISABLE_BUILTIN_INPUT_SYSTEM_WINDOWSMR
  366. InputSystem.RegisterLayout<UnityEngine.XR.WindowsMR.Input.WMRHMD>(
  367. matches: new InputDeviceMatcher()
  368. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  369. .WithProduct("(Windows Mixed Reality HMD)|(Microsoft HoloLens)|(^(WindowsMR Headset))")
  370. );
  371. InputSystem.RegisterLayout<UnityEngine.XR.WindowsMR.Input.WMRSpatialController>(
  372. matches: new InputDeviceMatcher()
  373. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  374. .WithProduct(@"(^(Spatial Controller))|(^(OpenVR Controller\(WindowsMR))")
  375. );
  376. InputSystem.RegisterLayout<UnityEngine.XR.WindowsMR.Input.HololensHand>(
  377. matches: new InputDeviceMatcher()
  378. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  379. .WithProduct(@"(^(Hand -))")
  380. );
  381. #endif
  382. // Built-in layouts replaced by the com.unity.xr.oculus package.
  383. #if !DISABLE_BUILTIN_INPUT_SYSTEM_OCULUS
  384. InputSystem.RegisterLayout<Unity.XR.Oculus.Input.OculusHMD>(
  385. matches: new InputDeviceMatcher()
  386. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  387. .WithProduct("^(Oculus Rift)|^(Oculus Quest)|^(Oculus Go)"));
  388. InputSystem.RegisterLayout<Unity.XR.Oculus.Input.OculusTouchController>(
  389. matches: new InputDeviceMatcher()
  390. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  391. .WithProduct(@"(^(Oculus Touch Controller))|(^(Oculus Quest Controller))"));
  392. InputSystem.RegisterLayout<Unity.XR.Oculus.Input.OculusRemote>(
  393. matches: new InputDeviceMatcher()
  394. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  395. .WithProduct(@"Oculus Remote"));
  396. InputSystem.RegisterLayout<Unity.XR.Oculus.Input.OculusTrackingReference>(
  397. matches: new InputDeviceMatcher()
  398. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  399. .WithProduct(@"((Tracking Reference)|(^(Oculus Rift [a-zA-Z0-9]* \(Camera)))"));
  400. InputSystem.RegisterLayout<Unity.XR.Oculus.Input.OculusHMDExtended>(
  401. name: "GearVR",
  402. matches: new InputDeviceMatcher()
  403. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  404. .WithProduct("Oculus HMD"));
  405. InputSystem.RegisterLayout<Unity.XR.Oculus.Input.GearVRTrackedController>(
  406. matches: new InputDeviceMatcher()
  407. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  408. .WithProduct("^(Oculus Tracked Remote)"));
  409. #endif
  410. // Built-in layouts replaced by the com.unity.xr.googlevr package.
  411. #if !DISABLE_BUILTIN_INPUT_SYSTEM_GOOGLEVR
  412. InputSystem.RegisterLayout<Unity.XR.GoogleVr.DaydreamHMD>(
  413. matches: new InputDeviceMatcher()
  414. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  415. .WithProduct("Daydream HMD"));
  416. InputSystem.RegisterLayout<Unity.XR.GoogleVr.DaydreamController>(
  417. matches: new InputDeviceMatcher()
  418. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  419. .WithProduct("^(Daydream Controller)"));
  420. #endif
  421. // Built-in layouts replaced by the com.unity.xr.openvr package.
  422. #if !DISABLE_BUILTIN_INPUT_SYSTEM_OPENVR
  423. InputSystem.RegisterLayout<Unity.XR.OpenVR.OpenVRHMD>(
  424. matches: new InputDeviceMatcher()
  425. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  426. .WithProduct("^(OpenVR Headset)|^(Vive Pro)")
  427. );
  428. InputSystem.RegisterLayout<Unity.XR.OpenVR.OpenVRControllerWMR>(
  429. matches: new InputDeviceMatcher()
  430. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  431. .WithProduct("^(OpenVR Controller\\(WindowsMR)")
  432. );
  433. InputSystem.RegisterLayout<Unity.XR.OpenVR.ViveWand>(
  434. matches: new InputDeviceMatcher()
  435. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  436. .WithManufacturer("HTC")
  437. .WithProduct(@"^(OpenVR Controller\(((Vive. Controller)|(VIVE. Controller)|(Vive Controller)))")
  438. );
  439. InputSystem.RegisterLayout<Unity.XR.OpenVR.OpenVROculusTouchController>(
  440. matches: new InputDeviceMatcher()
  441. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  442. .WithProduct(@"^(OpenVR Controller\(Oculus)")
  443. );
  444. InputSystem.RegisterLayout<Unity.XR.OpenVR.ViveTracker>(
  445. matches: new InputDeviceMatcher()
  446. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  447. .WithManufacturer("HTC")
  448. .WithProduct(@"^(VIVE Tracker)")
  449. );
  450. InputSystem.RegisterLayout<Unity.XR.OpenVR.HandedViveTracker>(
  451. matches: new InputDeviceMatcher()
  452. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  453. .WithManufacturer("HTC")
  454. .WithProduct(@"^(OpenVR Controller\(VIVE Tracker)")
  455. );
  456. InputSystem.RegisterLayout<Unity.XR.OpenVR.ViveLighthouse>(
  457. matches: new InputDeviceMatcher()
  458. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  459. .WithManufacturer("HTC")
  460. .WithProduct(@"^(HTC V2-XD/XE)")
  461. );
  462. #endif
  463. #endif
  464. }
  465. }
  466. }
  467. #endif