2021년 4학년 1학기 기업연계프로젝트2 컴퓨터소프트웨어공학과 <원광투어팀> 팀장 : 송유진 팀원 : 김나영, 이경희, 한유진
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.

1033 lines
48 KiB

5 years ago
  1. //========= Copyright 2016-2020, HTC Corporation. All rights reserved. ===========
  2. using HTC.UnityPlugin.Utility;
  3. using HTC.UnityPlugin.Vive;
  4. using System.Collections.Generic;
  5. using System.Text.RegularExpressions;
  6. using UnityEngine;
  7. #if UNITY_2017_2_OR_NEWER
  8. using UnityEngine.XR;
  9. #endif
  10. #if VIU_XR_GENERAL_SETTINGS
  11. using UnityEngine.XR.Management;
  12. using UnityEngine.SpatialTracking;
  13. using System;
  14. #if VIU_WAVEXR_ESSENCE_RENDERMODEL
  15. using Wave.Essence;
  16. #endif
  17. #endif
  18. namespace HTC.UnityPlugin.VRModuleManagement
  19. {
  20. public enum XRInputSubsystemType
  21. {
  22. Unknown,
  23. OpenVR,
  24. Oculus,
  25. WMR,
  26. MagicLeap,
  27. }
  28. public sealed class UnityXRModule : VRModule.ModuleBase
  29. {
  30. public override int moduleOrder { get { return (int)DefaultModuleOrder.UnityXR; } }
  31. public override int moduleIndex { get { return (int)VRModuleSelectEnum.UnityXR; } }
  32. public const string WAVE_XR_LOADER_NAME = "Wave XR Loader";
  33. public const string WAVE_XR_LOADER_CLASS_NAME = "WaveXRLoader";
  34. #if UNITY_2019_3_OR_NEWER && VIU_XR_GENERAL_SETTINGS
  35. private class CameraCreator : VRCameraHook.CameraCreator
  36. {
  37. public override bool shouldActive { get { return s_moduleInstance != null && s_moduleInstance.isActivated; } }
  38. public override void CreateCamera(VRCameraHook hook)
  39. {
  40. if (hook.GetComponent<TrackedPoseDriver>() == null)
  41. {
  42. hook.gameObject.AddComponent<TrackedPoseDriver>();
  43. }
  44. }
  45. }
  46. [RenderModelHook.CreatorPriorityAttirbute(0)]
  47. private class RenderModelCreator : RenderModelHook.DefaultRenderModelCreator
  48. {
  49. #if VIU_WAVEXR_ESSENCE_RENDERMODEL
  50. private uint m_index = INVALID_DEVICE_INDEX;
  51. #endif
  52. public override bool shouldActive { get { return s_moduleInstance == null ? false : s_moduleInstance.isActivated; } }
  53. public override void UpdateRenderModel()
  54. {
  55. #if VIU_WAVEXR_ESSENCE_RENDERMODEL
  56. if (HasActiveLoader(WAVE_XR_LOADER_NAME))
  57. {
  58. if (!ChangeProp.Set(ref m_index, hook.GetModelDeviceIndex())) { return; }
  59. if (VRModule.IsValidDeviceIndex(m_index) && m_index == VRModule.GetRightControllerDeviceIndex())
  60. {
  61. var go = new GameObject("Model");
  62. go.transform.SetParent(hook.transform, false);
  63. go.AddComponent<Wave.Essence.Controller.RenderModel>();
  64. go.AddComponent<Wave.Essence.Controller.ButtonEffect>();
  65. go.AddComponent<Wave.Essence.Controller.ShowIndicator>();
  66. }
  67. else if (VRModule.IsValidDeviceIndex(m_index) && m_index == VRModule.GetLeftControllerDeviceIndex())
  68. {
  69. var go = new GameObject("Model");
  70. go.transform.SetParent(hook.transform, false);
  71. var rm = go.AddComponent<Wave.Essence.Controller.RenderModel>();
  72. rm.transform.gameObject.SetActive(false);
  73. rm.WhichHand = XR_Hand.NonDominant;
  74. rm.transform.gameObject.SetActive(true);
  75. var be = go.AddComponent<Wave.Essence.Controller.ButtonEffect>();
  76. be.transform.gameObject.SetActive(false);
  77. be.HandType = XR_Hand.NonDominant;
  78. be.transform.gameObject.SetActive(true);
  79. go.AddComponent<Wave.Essence.Controller.ShowIndicator>();
  80. }
  81. else
  82. {
  83. // deacitvate object for render model
  84. if (m_model != null)
  85. {
  86. m_model.gameObject.SetActive(false);
  87. }
  88. }
  89. }
  90. else
  91. #endif
  92. {
  93. base.UpdateRenderModel();
  94. }
  95. }
  96. }
  97. private class HapticVibrationState
  98. {
  99. public uint deviceIndex;
  100. public float amplitude;
  101. public float remainingDuration;
  102. public float remainingDelay;
  103. public HapticVibrationState(uint index, float amp, float duration, float delay)
  104. {
  105. deviceIndex = index;
  106. amplitude = amp;
  107. remainingDuration = duration;
  108. remainingDelay = delay;
  109. }
  110. }
  111. private const uint DEVICE_STATE_LENGTH = 16;
  112. private static UnityXRModule s_moduleInstance;
  113. private XRInputSubsystemType m_currentInputSubsystemType = XRInputSubsystemType.Unknown;
  114. private uint m_rightHandedDeviceIndex = INVALID_DEVICE_INDEX;
  115. private uint m_leftHandedDeviceIndex = INVALID_DEVICE_INDEX;
  116. private Dictionary<int, uint> m_deviceUidToIndex = new Dictionary<int, uint>();
  117. private List<InputDevice> m_indexToDevices = new List<InputDevice>();
  118. private List<InputDevice> m_connectedDevices = new List<InputDevice>();
  119. private List<HapticVibrationState> m_activeHapticVibrationStates = new List<HapticVibrationState>();
  120. public static bool HasActiveLoader(string loaderName = null)
  121. {
  122. var instance = XRGeneralSettings.Instance;
  123. if (instance == null) { return false; }
  124. var manager = instance.Manager;
  125. if (manager == null) { return false; }
  126. var loader = manager.activeLoader;
  127. if (loader == null) { return false; }
  128. if (loaderName != null && loaderName != loader.name) { return false; }
  129. return true;
  130. }
  131. public override bool ShouldActiveModule()
  132. {
  133. return VIUSettings.activateUnityXRModule && HasActiveLoader();
  134. }
  135. public override void OnActivated()
  136. {
  137. s_moduleInstance = this;
  138. m_currentInputSubsystemType = DetectCurrentInputSubsystemType();
  139. EnsureDeviceStateLength(DEVICE_STATE_LENGTH);
  140. UpdateTrackingSpaceType();
  141. Debug.Log("Activated XRLoader Name: " + XRGeneralSettings.Instance.Manager.activeLoader.name);
  142. }
  143. public override void OnDeactivated()
  144. {
  145. s_moduleInstance = null;
  146. m_deviceUidToIndex.Clear();
  147. m_indexToDevices.Clear();
  148. m_connectedDevices.Clear();
  149. }
  150. public override uint GetLeftControllerDeviceIndex() { return m_leftHandedDeviceIndex; }
  151. public override uint GetRightControllerDeviceIndex() { return m_rightHandedDeviceIndex; }
  152. public override void UpdateTrackingSpaceType()
  153. {
  154. switch (VRModule.trackingSpaceType)
  155. {
  156. case VRModuleTrackingSpaceType.Stationary:
  157. SetAllXRInputSubsystemTrackingOriginMode(TrackingOriginModeFlags.Device);
  158. break;
  159. case VRModuleTrackingSpaceType.RoomScale:
  160. SetAllXRInputSubsystemTrackingOriginMode(TrackingOriginModeFlags.Floor);
  161. break;
  162. }
  163. }
  164. // NOTE: Frequency not supported
  165. public override void TriggerHapticVibration(uint deviceIndex, float durationSeconds = 0.01f, float frequency = 85.0f, float amplitude = 0.125f, float startSecondsFromNow = 0.0f)
  166. {
  167. InputDevice device;
  168. if (TryGetDevice(deviceIndex, out device))
  169. {
  170. if (!device.isValid)
  171. {
  172. return;
  173. }
  174. HapticCapabilities capabilities;
  175. if (device.TryGetHapticCapabilities(out capabilities))
  176. {
  177. if (capabilities.supportsImpulse)
  178. {
  179. for (int i = m_activeHapticVibrationStates.Count - 1; i >= 0; i--)
  180. {
  181. if (m_activeHapticVibrationStates[i].deviceIndex == deviceIndex)
  182. {
  183. m_activeHapticVibrationStates.RemoveAt(i);
  184. }
  185. }
  186. m_activeHapticVibrationStates.Add(new HapticVibrationState(deviceIndex, amplitude, durationSeconds, startSecondsFromNow));
  187. }
  188. }
  189. }
  190. }
  191. public override void Update()
  192. {
  193. UpdateLockPhysicsUpdateRate();
  194. UpdateHapticVibration();
  195. }
  196. public override void BeforeRenderUpdate()
  197. {
  198. IVRModuleDeviceState prevState;
  199. IVRModuleDeviceStateRW currState;
  200. uint deviceIndex;
  201. FlushDeviceState();
  202. // mark all devices as disconnected
  203. deviceIndex = 0u;
  204. while (TryGetValidDeviceState(deviceIndex++, out prevState, out currState))
  205. {
  206. currState.isConnected = false;
  207. }
  208. bool roleChanged = false;
  209. InputDevices.GetDevices(m_connectedDevices);
  210. foreach (InputDevice device in m_connectedDevices)
  211. {
  212. deviceIndex = GetOrCreateDeviceIndex(device);
  213. EnsureValidDeviceState(deviceIndex, out prevState, out currState);
  214. if (!prevState.isConnected)
  215. {
  216. currState.deviceClass = GetDeviceClass(device.name, device.characteristics);
  217. currState.serialNumber = device.name + " " + device.serialNumber + " " + (int)device.characteristics;
  218. currState.modelNumber = device.name;
  219. currState.renderModelName = device.name;
  220. SetupKnownDeviceModel(currState);
  221. if ((device.characteristics & InputDeviceCharacteristics.Left) > 0u)
  222. {
  223. m_leftHandedDeviceIndex = deviceIndex;
  224. roleChanged = true;
  225. }
  226. else if ((device.characteristics & InputDeviceCharacteristics.Right) > 0u)
  227. {
  228. m_rightHandedDeviceIndex = deviceIndex;
  229. roleChanged = true;
  230. }
  231. Debug.LogFormat("Device connected: {0} / {1} / {2} / {3} / {4} / {5} ({6})", deviceIndex, currState.deviceClass, currState.deviceModel, currState.modelNumber, currState.serialNumber, device.name, device.characteristics);
  232. }
  233. bool isTracked = false;
  234. device.TryGetFeatureValue(CommonUsages.isTracked, out isTracked);
  235. currState.isPoseValid = device.isValid && isTracked;
  236. currState.isConnected = true;
  237. UpdateTrackingState(currState, device);
  238. if (currState.deviceClass == VRModuleDeviceClass.Controller || currState.deviceModel == VRModuleDeviceModel.ViveTracker)
  239. {
  240. UpdateControllerState(currState, device);
  241. }
  242. }
  243. //UpdateHandHeldDeviceIndex();
  244. deviceIndex = 0u;
  245. // reset all devices that is not connected in this frame
  246. while (TryGetValidDeviceState(deviceIndex, out prevState, out currState))
  247. {
  248. if (!currState.isConnected)
  249. {
  250. currState.Reset();
  251. if (deviceIndex == m_leftHandedDeviceIndex)
  252. {
  253. m_leftHandedDeviceIndex = VRModule.INVALID_DEVICE_INDEX;
  254. roleChanged = true;
  255. }
  256. else if (deviceIndex == m_rightHandedDeviceIndex)
  257. {
  258. m_rightHandedDeviceIndex = VRModule.INVALID_DEVICE_INDEX;
  259. roleChanged = true;
  260. }
  261. }
  262. ++deviceIndex;
  263. }
  264. if (roleChanged) { InvokeControllerRoleChangedEvent(); }
  265. ProcessConnectedDeviceChanged();
  266. ProcessDevicePoseChanged();
  267. ProcessDeviceInputChanged();
  268. }
  269. private void UpdateLockPhysicsUpdateRate()
  270. {
  271. if (VRModule.lockPhysicsUpdateRateToRenderFrequency && Time.timeScale > 0.0f)
  272. {
  273. List<XRDisplaySubsystem> displaySystems = new List<XRDisplaySubsystem>();
  274. SubsystemManager.GetInstances<XRDisplaySubsystem>(displaySystems);
  275. float minRefreshRate = float.MaxValue;
  276. foreach (XRDisplaySubsystem system in displaySystems)
  277. {
  278. float rate = 60.0f;
  279. if (system.TryGetDisplayRefreshRate(out rate))
  280. {
  281. if (rate < minRefreshRate)
  282. {
  283. minRefreshRate = rate;
  284. }
  285. }
  286. }
  287. if (minRefreshRate > 0 && minRefreshRate < float.MaxValue)
  288. {
  289. Time.fixedDeltaTime = 1.0f / minRefreshRate;
  290. }
  291. }
  292. }
  293. private void UpdateHapticVibration()
  294. {
  295. for (int i = m_activeHapticVibrationStates.Count - 1; i >= 0; i--)
  296. {
  297. HapticVibrationState state = m_activeHapticVibrationStates[i];
  298. if (state.remainingDelay > 0.0f)
  299. {
  300. state.remainingDelay -= Time.deltaTime;
  301. continue;
  302. }
  303. InputDevice device;
  304. if (TryGetDevice(state.deviceIndex, out device))
  305. {
  306. if (device.isValid)
  307. {
  308. device.SendHapticImpulse(0, state.amplitude);
  309. }
  310. }
  311. state.remainingDuration -= Time.deltaTime;
  312. if (state.remainingDuration <= 0)
  313. {
  314. m_activeHapticVibrationStates.RemoveAt(i);
  315. }
  316. }
  317. }
  318. private void UpdateTrackingState(IVRModuleDeviceStateRW state, InputDevice device)
  319. {
  320. Vector3 position = Vector3.zero;
  321. if (device.TryGetFeatureValue(CommonUsages.devicePosition, out position))
  322. {
  323. state.position = position;
  324. }
  325. Quaternion rotation = Quaternion.identity;
  326. if (device.TryGetFeatureValue(CommonUsages.deviceRotation, out rotation))
  327. {
  328. state.rotation = rotation;
  329. }
  330. Vector3 velocity = Vector3.zero;
  331. if (device.TryGetFeatureValue(CommonUsages.deviceVelocity, out velocity))
  332. {
  333. state.velocity = velocity;
  334. }
  335. Vector3 angularVelocity = Vector3.zero;
  336. if (device.TryGetFeatureValue(CommonUsages.deviceAngularVelocity, out angularVelocity))
  337. {
  338. state.angularVelocity = angularVelocity;
  339. }
  340. }
  341. private void UpdateControllerState(IVRModuleDeviceStateRW state, InputDevice device)
  342. {
  343. switch (state.deviceModel)
  344. {
  345. case VRModuleDeviceModel.ViveController:
  346. UpdateViveControllerState(state, device);
  347. break;
  348. case VRModuleDeviceModel.ViveCosmosControllerLeft:
  349. case VRModuleDeviceModel.ViveCosmosControllerRight:
  350. UpdateViveCosmosControllerState(state, device);
  351. break;
  352. case VRModuleDeviceModel.ViveTracker:
  353. UpdateViveTrackerState(state, device);
  354. break;
  355. case VRModuleDeviceModel.OculusTouchLeft:
  356. case VRModuleDeviceModel.OculusTouchRight:
  357. case VRModuleDeviceModel.OculusGoController:
  358. case VRModuleDeviceModel.OculusQuestControllerLeft:
  359. case VRModuleDeviceModel.OculusQuestControllerRight:
  360. UpdateOculusControllerState(state, device);
  361. break;
  362. case VRModuleDeviceModel.WMRControllerLeft:
  363. case VRModuleDeviceModel.WMRControllerRight:
  364. UpdateWMRControllerState(state, device);
  365. break;
  366. case VRModuleDeviceModel.KnucklesLeft:
  367. case VRModuleDeviceModel.KnucklesRight:
  368. case VRModuleDeviceModel.IndexControllerLeft:
  369. case VRModuleDeviceModel.IndexControllerRight:
  370. UpdateIndexControllerState(state, device);
  371. break;
  372. case VRModuleDeviceModel.MagicLeapController:
  373. UpdateMagicLeapControllerState(state, device);
  374. break;
  375. case VRModuleDeviceModel.ViveFocusChirp:
  376. UpdateViveFocusChirpControllerState(state, device);
  377. break;
  378. case VRModuleDeviceModel.ViveFocusFinch:
  379. UpdateViveFocusFinchControllerState(state, device);
  380. break;
  381. }
  382. }
  383. private bool TryGetDevice(uint index, out InputDevice deviceOut)
  384. {
  385. deviceOut = default;
  386. if (index < m_indexToDevices.Count)
  387. {
  388. deviceOut = m_indexToDevices[(int)index];
  389. return true;
  390. }
  391. return false;
  392. }
  393. private uint GetOrCreateDeviceIndex(InputDevice device)
  394. {
  395. uint index = 0;
  396. int uid = GetDeviceUID(device);
  397. if (m_deviceUidToIndex.TryGetValue(uid, out index))
  398. {
  399. return index;
  400. }
  401. uint newIndex = (uint)m_deviceUidToIndex.Count;
  402. m_deviceUidToIndex.Add(uid, newIndex);
  403. m_indexToDevices.Add(device);
  404. return newIndex;
  405. }
  406. private VRModuleDeviceClass GetDeviceClass(string name, InputDeviceCharacteristics characteristics)
  407. {
  408. bool isTracker = Regex.IsMatch(name, @"tracker", RegexOptions.IgnoreCase);
  409. if ((characteristics & InputDeviceCharacteristics.HeadMounted) != 0)
  410. {
  411. return VRModuleDeviceClass.HMD;
  412. }
  413. if ((characteristics & InputDeviceCharacteristics.Controller) != 0 && !isTracker)
  414. {
  415. return VRModuleDeviceClass.Controller;
  416. }
  417. if ((characteristics & InputDeviceCharacteristics.TrackingReference) != 0)
  418. {
  419. return VRModuleDeviceClass.TrackingReference;
  420. }
  421. if ((characteristics & InputDeviceCharacteristics.TrackedDevice) != 0)
  422. {
  423. return VRModuleDeviceClass.GenericTracker;
  424. }
  425. return VRModuleDeviceClass.Invalid;
  426. }
  427. private void SetAllXRInputSubsystemTrackingOriginMode(TrackingOriginModeFlags mode)
  428. {
  429. List<XRInputSubsystem> systems = new List<XRInputSubsystem>();
  430. SubsystemManager.GetInstances(systems);
  431. foreach (XRInputSubsystem system in systems)
  432. {
  433. if (!system.TrySetTrackingOriginMode(mode))
  434. {
  435. Debug.LogWarning("Failed to set TrackingOriginModeFlags to XRInputSubsystem: " + system.SubsystemDescriptor.id);
  436. }
  437. }
  438. }
  439. private int GetDeviceUID(InputDevice device)
  440. {
  441. #if CSHARP_7_OR_LATER
  442. return (device.name, device.serialNumber, device.characteristics).GetHashCode();
  443. #else
  444. return new { device.name, device.serialNumber, device.characteristics }.GetHashCode();
  445. #endif
  446. }
  447. private XRInputSubsystemType DetectCurrentInputSubsystemType()
  448. {
  449. List<XRInputSubsystem> systems = new List<XRInputSubsystem>();
  450. SubsystemManager.GetInstances(systems);
  451. if (systems.Count == 0)
  452. {
  453. Debug.LogWarning("No XRInputSubsystem detected.");
  454. return XRInputSubsystemType.Unknown;
  455. }
  456. string id = systems[0].SubsystemDescriptor.id;
  457. Debug.Log("Activated XRInputSubsystem Name: " + id);
  458. if (Regex.IsMatch(id, @"openvr", RegexOptions.IgnoreCase))
  459. {
  460. return XRInputSubsystemType.OpenVR;
  461. }
  462. else if (Regex.IsMatch(id, @"oculus", RegexOptions.IgnoreCase))
  463. {
  464. return XRInputSubsystemType.Oculus;
  465. }
  466. else if (Regex.IsMatch(id, @"windows mixed reality", RegexOptions.IgnoreCase))
  467. {
  468. return XRInputSubsystemType.WMR;
  469. }
  470. else if (Regex.IsMatch(id, @"magicleap", RegexOptions.IgnoreCase))
  471. {
  472. return XRInputSubsystemType.MagicLeap;
  473. }
  474. return XRInputSubsystemType.Unknown;
  475. }
  476. private void UpdateViveControllerState(IVRModuleDeviceStateRW state, InputDevice device)
  477. {
  478. bool menuButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.menuButton);
  479. bool primaryAxisClick = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxisClick);
  480. bool triggerButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.triggerButton);
  481. bool primary2DAxisTouch = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxisTouch);
  482. bool gripButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.gripButton);
  483. float trigger = GetDeviceFeatureValueOrDefault(device, CommonUsages.trigger);
  484. Vector2 primary2DAxis = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxis);
  485. state.SetButtonPress(VRModuleRawButton.ApplicationMenu, menuButton);
  486. state.SetButtonPress(VRModuleRawButton.Touchpad, primaryAxisClick);
  487. state.SetButtonPress(VRModuleRawButton.Grip, gripButton);
  488. state.SetButtonPress(VRModuleRawButton.CapSenseGrip, gripButton);
  489. state.SetButtonPress(VRModuleRawButton.Trigger, triggerButton);
  490. state.SetButtonTouch(VRModuleRawButton.Trigger, triggerButton);
  491. state.SetButtonTouch(VRModuleRawButton.Touchpad, primary2DAxisTouch);
  492. state.SetAxisValue(VRModuleRawAxis.Trigger, trigger);
  493. state.SetAxisValue(VRModuleRawAxis.TouchpadX, primary2DAxis.x);
  494. state.SetAxisValue(VRModuleRawAxis.TouchpadY, primary2DAxis.y);
  495. }
  496. private void UpdateViveCosmosControllerState(IVRModuleDeviceStateRW state, InputDevice device)
  497. {
  498. bool primaryButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.primaryButton); // X/A
  499. bool primaryTouch = GetDeviceFeatureValueOrDefault(device, CommonUsages.primaryTouch); // X/A
  500. bool secondaryButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.secondaryButton); // Y/B
  501. bool secondaryTouch = GetDeviceFeatureValueOrDefault(device, CommonUsages.secondaryTouch); // Y/B
  502. bool primaryAxisClick = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxisClick);
  503. bool primary2DAxisTouch = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxisTouch);
  504. bool triggerButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.triggerButton);
  505. bool triggerTouch = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<bool>("TriggerTouch"));
  506. bool gripButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.gripButton);
  507. bool bumperButton = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<bool>("BumperButton"));
  508. float trigger = GetDeviceFeatureValueOrDefault(device, CommonUsages.trigger);
  509. Vector2 primary2DAxis = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxis);
  510. state.SetButtonPress(VRModuleRawButton.A, primaryButton);
  511. state.SetButtonPress(VRModuleRawButton.ApplicationMenu, secondaryButton);
  512. state.SetButtonPress(VRModuleRawButton.Touchpad, primaryAxisClick);
  513. state.SetButtonPress(VRModuleRawButton.Trigger, triggerButton);
  514. state.SetButtonPress(VRModuleRawButton.Grip, gripButton);
  515. state.SetButtonPress(VRModuleRawButton.Bumper, bumperButton);
  516. state.SetButtonTouch(VRModuleRawButton.A, primaryTouch);
  517. state.SetButtonTouch(VRModuleRawButton.ApplicationMenu, secondaryTouch);
  518. state.SetButtonTouch(VRModuleRawButton.Touchpad, primary2DAxisTouch);
  519. state.SetButtonTouch(VRModuleRawButton.Trigger, triggerTouch);
  520. state.SetButtonTouch(VRModuleRawButton.Grip, gripButton);
  521. state.SetButtonTouch(VRModuleRawButton.Bumper, bumperButton);
  522. state.SetAxisValue(VRModuleRawAxis.Trigger, trigger);
  523. state.SetAxisValue(VRModuleRawAxis.TouchpadX, primary2DAxis.x);
  524. state.SetAxisValue(VRModuleRawAxis.TouchpadY, primary2DAxis.y);
  525. }
  526. private void UpdateViveTrackerState(IVRModuleDeviceStateRW state, InputDevice device)
  527. {
  528. bool menuButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.menuButton);
  529. bool primary2DAxisClick = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxisClick);
  530. bool primary2DAxisTouch = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxisTouch);
  531. bool gripButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.gripButton);
  532. bool triggerButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.triggerButton);
  533. float trigger = GetDeviceFeatureValueOrDefault(device, CommonUsages.trigger);
  534. Vector2 primary2DAxis = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxis);
  535. state.SetButtonPress(VRModuleRawButton.ApplicationMenu, menuButton);
  536. state.SetButtonPress(VRModuleRawButton.Touchpad, primary2DAxisClick);
  537. state.SetButtonPress(VRModuleRawButton.Grip, gripButton);
  538. state.SetButtonPress(VRModuleRawButton.CapSenseGrip, gripButton);
  539. state.SetButtonPress(VRModuleRawButton.Trigger, triggerButton);
  540. state.SetButtonTouch(VRModuleRawButton.Trigger, triggerButton);
  541. state.SetButtonTouch(VRModuleRawButton.Touchpad, primary2DAxisTouch);
  542. state.SetAxisValue(VRModuleRawAxis.Trigger, trigger);
  543. state.SetAxisValue(VRModuleRawAxis.TouchpadX, primary2DAxis.x);
  544. state.SetAxisValue(VRModuleRawAxis.TouchpadY, primary2DAxis.y);
  545. }
  546. private void UpdateOculusControllerState(IVRModuleDeviceStateRW state, InputDevice device)
  547. {
  548. bool primaryButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.primaryButton); // X/A
  549. bool secondaryButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.secondaryButton); // Y/B
  550. bool triggerButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.triggerButton);
  551. bool gripButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.gripButton);
  552. bool primaryTouch = GetDeviceFeatureValueOrDefault(device, CommonUsages.primaryTouch); // X/A
  553. bool secondaryTouch = GetDeviceFeatureValueOrDefault(device, CommonUsages.secondaryTouch); // Y/B
  554. bool primary2DAxisClick = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxisClick); // Joystick
  555. bool primary2DAxisTouch = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxisTouch); // Joystick
  556. float trigger = GetDeviceFeatureValueOrDefault(device, CommonUsages.trigger);
  557. float grip = GetDeviceFeatureValueOrDefault(device, CommonUsages.grip);
  558. Vector2 primary2DAxis = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxis); // Joystick
  559. state.SetButtonPress(VRModuleRawButton.A, primaryButton);
  560. state.SetButtonPress(VRModuleRawButton.ApplicationMenu, secondaryButton);
  561. state.SetButtonPress(VRModuleRawButton.Trigger, triggerButton);
  562. state.SetButtonPress(VRModuleRawButton.Grip, gripButton);
  563. state.SetButtonPress(VRModuleRawButton.CapSenseGrip, gripButton);
  564. state.SetButtonPress(VRModuleRawButton.Axis0, primary2DAxisClick);
  565. state.SetButtonTouch(VRModuleRawButton.A, primaryTouch);
  566. state.SetButtonTouch(VRModuleRawButton.ApplicationMenu, secondaryTouch);
  567. state.SetButtonTouch(VRModuleRawButton.Grip, grip >= 0.05f);
  568. state.SetButtonTouch(VRModuleRawButton.CapSenseGrip, grip >= 0.05f);
  569. state.SetButtonTouch(VRModuleRawButton.Axis0, primary2DAxisTouch);
  570. state.SetAxisValue(VRModuleRawAxis.Trigger, trigger);
  571. state.SetAxisValue(VRModuleRawAxis.CapSenseGrip, grip);
  572. state.SetAxisValue(VRModuleRawAxis.JoystickX, primary2DAxis.x);
  573. state.SetAxisValue(VRModuleRawAxis.JoystickY, primary2DAxis.y);
  574. if (m_currentInputSubsystemType == XRInputSubsystemType.OpenVR)
  575. {
  576. bool triggerTouch = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<bool>("TriggerTouch"));
  577. state.SetButtonTouch(VRModuleRawButton.Trigger, triggerTouch);
  578. }
  579. else if (m_currentInputSubsystemType == XRInputSubsystemType.Oculus)
  580. {
  581. bool thumbrest = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<bool>("Thumbrest"));
  582. float indexTouch = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<float>("IndexTouch"));
  583. float thumbTouch = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<float>("ThumbTouch")); // Not in use
  584. state.SetButtonTouch(VRModuleRawButton.Touchpad, thumbrest);
  585. state.SetButtonTouch(VRModuleRawButton.Trigger, indexTouch >= 1.0f);
  586. if ((device.characteristics & InputDeviceCharacteristics.Left) != 0)
  587. {
  588. bool menuButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.menuButton);
  589. state.SetButtonPress(VRModuleRawButton.System, menuButton);
  590. }
  591. }
  592. }
  593. private void UpdateWMRControllerState(IVRModuleDeviceStateRW state, InputDevice device)
  594. {
  595. bool menuButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.menuButton);
  596. bool triggerButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.triggerButton);
  597. bool gripButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.gripButton);
  598. bool primary2DAxisClick = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxisClick); // Touchpad
  599. bool secondary2DAxisClick = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<bool>("Secondary2DAxisClick"));
  600. bool primary2DAxisTouch = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxisTouch); // Touchpad
  601. float trigger = GetDeviceFeatureValueOrDefault(device, CommonUsages.trigger);
  602. Vector2 primary2DAxis = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxis); // Touchpad
  603. Vector2 secondary2DAxis = GetDeviceFeatureValueOrDefault(device, CommonUsages.secondary2DAxis); // Joystick
  604. state.SetButtonPress(VRModuleRawButton.ApplicationMenu, menuButton);
  605. state.SetButtonPress(VRModuleRawButton.Trigger, triggerButton);
  606. state.SetButtonPress(VRModuleRawButton.Grip, gripButton);
  607. state.SetButtonPress(VRModuleRawButton.Touchpad, primary2DAxisClick);
  608. state.SetButtonPress(VRModuleRawButton.Axis0, secondary2DAxisClick);
  609. state.SetButtonTouch(VRModuleRawButton.Touchpad, primary2DAxisTouch);
  610. state.SetAxisValue(VRModuleRawAxis.Trigger, trigger);
  611. state.SetAxisValue(VRModuleRawAxis.TouchpadX, primary2DAxis.x);
  612. state.SetAxisValue(VRModuleRawAxis.TouchpadY, primary2DAxis.y);
  613. state.SetAxisValue(VRModuleRawAxis.JoystickX, secondary2DAxis.x);
  614. state.SetAxisValue(VRModuleRawAxis.JoystickY, secondary2DAxis.y);
  615. if (m_currentInputSubsystemType == XRInputSubsystemType.WMR)
  616. {
  617. float grip = GetDeviceFeatureValueOrDefault(device, CommonUsages.grip);
  618. float sourceLossRisk = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<float>("SourceLossRisk")); // Not in use
  619. Vector3 pointerPosition = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<Vector3>("PointerPosition")); // Not in use
  620. Vector3 sourceMitigationDirection = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<Vector3>("SourceMitigationDirection")); // Not in use
  621. Quaternion pointerRotation = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<Quaternion>("PointerRotation")); // Not in use
  622. // conflict with JoystickX
  623. //state.SetAxisValue(VRModuleRawAxis.CapSenseGrip, grip);
  624. }
  625. }
  626. private void UpdateIndexControllerState(IVRModuleDeviceStateRW state, InputDevice device)
  627. {
  628. // TODO: Get finger curl values once OpenVR XR Plugin supports
  629. bool primaryButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.primaryButton);
  630. bool secondaryButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.secondaryButton); // B
  631. bool primary2DAxisClick = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxisClick);
  632. bool secondary2DAxisClick = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<bool>("Secondary2DAxisClick")); // Joystick
  633. bool triggerButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.triggerButton); // trigger >= 0.5
  634. bool gripButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.gripButton); // grip force >= 0.5
  635. bool primaryTouch = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<bool>("PrimaryTouch"));
  636. bool secondaryTouch = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<bool>("SecondaryTouch"));
  637. bool triggerTouch = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<bool>("TriggerTouch"));
  638. bool gripTouch = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<bool>("GripTouch"));
  639. bool gripGrab = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<bool>("GripGrab")); // gripCapacitive >= 0.7
  640. bool primary2DAxisTouch = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxisTouch);
  641. bool secondary2DAxisTouch = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<bool>("Secondary2DAxisTouch")); // Joystick
  642. float trigger = GetDeviceFeatureValueOrDefault(device, CommonUsages.trigger);
  643. float grip = GetDeviceFeatureValueOrDefault(device, CommonUsages.grip); // grip force
  644. float gripCapacitive = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<float>("GripCapacitive")); // touch area on grip
  645. Vector2 primary2DAxis = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxis);
  646. Vector2 secondary2DAxis = GetDeviceFeatureValueOrDefault(device, CommonUsages.secondary2DAxis);
  647. state.SetButtonPress(VRModuleRawButton.A, primaryButton);
  648. state.SetButtonPress(VRModuleRawButton.ApplicationMenu, secondaryButton);
  649. state.SetButtonPress(VRModuleRawButton.Touchpad, primary2DAxisClick);
  650. state.SetButtonPress(VRModuleRawButton.Trigger, triggerButton);
  651. state.SetButtonPress(VRModuleRawButton.Grip, gripButton);
  652. state.SetButtonPress(VRModuleRawButton.Axis0, secondary2DAxisClick);
  653. state.SetButtonTouch(VRModuleRawButton.A, primaryTouch);
  654. state.SetButtonTouch(VRModuleRawButton.ApplicationMenu, secondaryTouch);
  655. state.SetButtonTouch(VRModuleRawButton.Trigger, triggerTouch);
  656. state.SetButtonTouch(VRModuleRawButton.Grip, gripTouch);
  657. state.SetButtonTouch(VRModuleRawButton.Touchpad, primary2DAxisTouch);
  658. state.SetButtonTouch(VRModuleRawButton.Axis0, secondary2DAxisTouch);
  659. state.SetAxisValue(VRModuleRawAxis.TouchpadX, primary2DAxis.x);
  660. state.SetAxisValue(VRModuleRawAxis.TouchpadY, primary2DAxis.y);
  661. state.SetAxisValue(VRModuleRawAxis.JoystickX, secondary2DAxis.x);
  662. state.SetAxisValue(VRModuleRawAxis.JoystickY, secondary2DAxis.y);
  663. state.SetAxisValue(VRModuleRawAxis.Trigger, trigger);
  664. // conflict with JoystickX
  665. //state.SetAxisValue(VRModuleRawAxis.CapSenseGrip, grip);
  666. }
  667. private void UpdateMagicLeapControllerState(IVRModuleDeviceStateRW state, InputDevice device)
  668. {
  669. bool menuButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.menuButton);
  670. bool secondaryButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.secondaryButton); // Bumper
  671. bool triggerButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.triggerButton);
  672. bool primary2DAxisTouch = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxisTouch);
  673. uint MLControllerType = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<uint>("MLControllerType")); // Not in use
  674. uint MLControllerDOF = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<uint>("MLControllerDOF")); // Not in use
  675. uint MLControllerCalibrationAccuracy = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<uint>("MLControllerCalibrationAccuracy")); // Not in use
  676. float trigger = GetDeviceFeatureValueOrDefault(device, CommonUsages.trigger);
  677. float MLControllerTouch1Force = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<float>("MLControllerTouch1Force")); // Not in use
  678. float MLControllerTouch2Force = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<float>("MLControllerTouch2Force")); // Not in use
  679. Vector2 primary2DAxis = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxis);
  680. Vector2 secondary2DAxis = GetDeviceFeatureValueOrDefault(device, CommonUsages.secondary2DAxis); // Not in use
  681. state.SetButtonPress(VRModuleRawButton.ApplicationMenu, menuButton);
  682. state.SetButtonPress(VRModuleRawButton.Trigger, triggerButton);
  683. state.SetButtonPress(VRModuleRawButton.Bumper, secondaryButton);
  684. state.SetButtonTouch(VRModuleRawButton.Touchpad, primary2DAxisTouch);
  685. state.SetAxisValue(VRModuleRawAxis.Trigger, trigger);
  686. state.SetAxisValue(VRModuleRawAxis.TouchpadX, primary2DAxis.x);
  687. state.SetAxisValue(VRModuleRawAxis.TouchpadY, primary2DAxis.y);
  688. }
  689. private void UpdateViveFocusChirpControllerState(IVRModuleDeviceStateRW state, InputDevice device)
  690. {
  691. bool primary2DAxisClick = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxisClick); // Touchpad
  692. bool primary2DAxisTouch = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxisTouch); // Touchpad
  693. bool secondary2DAxisClick = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<bool>("Secondary2DAxisClick")); // No data
  694. bool secondary2DAxisTouch = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<bool>("Secondary2DAxisTouch")); // No data
  695. bool gripButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.gripButton);
  696. bool triggerButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.triggerButton);
  697. bool menuButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.menuButton);
  698. float trigger = GetDeviceFeatureValueOrDefault(device, CommonUsages.trigger);
  699. Vector2 primary2DAxis = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxis); // Touchpad
  700. Vector2 secondary2DAxis = GetDeviceFeatureValueOrDefault(device, CommonUsages.secondary2DAxis); // No data
  701. Vector2 dPad = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<Vector2>("DPad"));
  702. state.SetButtonPress(VRModuleRawButton.Touchpad, primary2DAxisClick);
  703. state.SetButtonPress(VRModuleRawButton.Grip, gripButton);
  704. state.SetButtonPress(VRModuleRawButton.Trigger, triggerButton);
  705. state.SetButtonPress(VRModuleRawButton.ApplicationMenu, menuButton);
  706. state.SetButtonPress(VRModuleRawButton.DPadUp, dPad.y > 0);
  707. state.SetButtonPress(VRModuleRawButton.DPadDown, dPad.y < 0);
  708. state.SetButtonPress(VRModuleRawButton.DPadLeft, dPad.x < 0);
  709. state.SetButtonPress(VRModuleRawButton.DPadRight, dPad.x > 0);
  710. state.SetButtonTouch(VRModuleRawButton.Touchpad, primary2DAxisTouch);
  711. state.SetAxisValue(VRModuleRawAxis.Trigger, trigger);
  712. state.SetAxisValue(VRModuleRawAxis.TouchpadX, primary2DAxis.x);
  713. state.SetAxisValue(VRModuleRawAxis.TouchpadY, primary2DAxis.y);
  714. }
  715. private void UpdateViveFocusFinchControllerState(IVRModuleDeviceStateRW state, InputDevice device)
  716. {
  717. bool primary2DAxisClick = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxisClick); // Touchpad
  718. bool primary2DAxisTouch = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxisTouch); // Touchpad
  719. bool secondary2DAxisClick = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<bool>("Secondary2DAxisClick")); // No data
  720. bool secondary2DAxisTouch = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<bool>("Secondary2DAxisTouch")); // No data
  721. bool gripButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.gripButton); // Trigger
  722. bool menuButton = GetDeviceFeatureValueOrDefault(device, CommonUsages.menuButton); // No Data
  723. float trigger = GetDeviceFeatureValueOrDefault(device, CommonUsages.trigger); // No Data
  724. Vector2 primary2DAxis = GetDeviceFeatureValueOrDefault(device, CommonUsages.primary2DAxis); // Touchpad
  725. Vector2 secondary2DAxis = GetDeviceFeatureValueOrDefault(device, CommonUsages.secondary2DAxis); // No data
  726. Vector2 dPad = GetDeviceFeatureValueOrDefault(device, new InputFeatureUsage<Vector2>("DPad")); // No Data
  727. state.SetButtonPress(VRModuleRawButton.Touchpad, primary2DAxisClick);
  728. state.SetButtonPress(VRModuleRawButton.Trigger, gripButton);
  729. state.SetButtonPress(VRModuleRawButton.ApplicationMenu, menuButton);
  730. state.SetButtonPress(VRModuleRawButton.DPadUp, dPad.y > 0);
  731. state.SetButtonPress(VRModuleRawButton.DPadDown, dPad.y < 0);
  732. state.SetButtonPress(VRModuleRawButton.DPadLeft, dPad.x < 0);
  733. state.SetButtonPress(VRModuleRawButton.DPadRight, dPad.x > 0);
  734. state.SetButtonTouch(VRModuleRawButton.Touchpad, primary2DAxisTouch);
  735. state.SetAxisValue(VRModuleRawAxis.Trigger, trigger);
  736. state.SetAxisValue(VRModuleRawAxis.TouchpadX, primary2DAxis.x);
  737. state.SetAxisValue(VRModuleRawAxis.TouchpadY, primary2DAxis.y);
  738. }
  739. private bool GetDeviceFeatureValueOrDefault(InputDevice device, InputFeatureUsage<bool> feature)
  740. {
  741. bool value = false;
  742. if (device.TryGetFeatureValue(feature, out value))
  743. {
  744. return value;
  745. }
  746. #if UNITY_EDITOR
  747. Debug.LogWarningFormat("Device {0} doesn't have bool feature {1}. Return default value instead.", device.name, feature.name);
  748. #endif
  749. return default;
  750. }
  751. private uint GetDeviceFeatureValueOrDefault(InputDevice device, InputFeatureUsage<uint> feature)
  752. {
  753. uint value = 0;
  754. if (device.TryGetFeatureValue(feature, out value))
  755. {
  756. return value;
  757. }
  758. #if UNITY_EDITOR
  759. Debug.LogWarningFormat("Device {0} doesn't have uint feature {1}. Return default value instead.", device.name, feature.name);
  760. #endif
  761. return default;
  762. }
  763. private float GetDeviceFeatureValueOrDefault(InputDevice device, InputFeatureUsage<float> feature)
  764. {
  765. float value = 0.0f;
  766. if (device.TryGetFeatureValue(feature, out value))
  767. {
  768. return value;
  769. }
  770. #if UNITY_EDITOR
  771. Debug.LogWarningFormat("Device {0} doesn't have float feature {1}. Return default value instead.", device.name, feature.name);
  772. #endif
  773. return default;
  774. }
  775. private Vector2 GetDeviceFeatureValueOrDefault(InputDevice device, InputFeatureUsage<Vector2> feature)
  776. {
  777. Vector2 value = Vector2.zero;
  778. if (device.TryGetFeatureValue(feature, out value))
  779. {
  780. return value;
  781. }
  782. #if UNITY_EDITOR
  783. Debug.LogWarningFormat("Device {0} doesn't have Vector2 feature {1}. Return default value instead.", device.name, feature.name);
  784. #endif
  785. return default;
  786. }
  787. private Vector3 GetDeviceFeatureValueOrDefault(InputDevice device, InputFeatureUsage<Vector3> feature)
  788. {
  789. Vector3 value = Vector3.zero;
  790. if (device.TryGetFeatureValue(feature, out value))
  791. {
  792. return value;
  793. }
  794. #if UNITY_EDITOR
  795. Debug.LogWarningFormat("Device {0} doesn't have Vector3 feature {1}. Return default value instead.", device.name, feature.name);
  796. #endif
  797. return default;
  798. }
  799. private Quaternion GetDeviceFeatureValueOrDefault(InputDevice device, InputFeatureUsage<Quaternion> feature)
  800. {
  801. Quaternion value = Quaternion.identity;
  802. if (device.TryGetFeatureValue(feature, out value))
  803. {
  804. return value;
  805. }
  806. #if UNITY_EDITOR
  807. Debug.LogWarningFormat("Device {0} doesn't have Quaternion feature {1}. Return default value instead.", device.name, feature.name);
  808. #endif
  809. return default;
  810. }
  811. private UnityEngine.XR.Hand GetDeviceFeatureValueOrDefault(InputDevice device, InputFeatureUsage<UnityEngine.XR.Hand> feature)
  812. {
  813. UnityEngine.XR.Hand value;
  814. if (device.TryGetFeatureValue(feature, out value))
  815. {
  816. return value;
  817. }
  818. #if UNITY_EDITOR
  819. Debug.LogWarningFormat("Device {0} doesn't have Hand feature {1}. Return default value instead.", device.name, feature.name);
  820. #endif
  821. return default;
  822. }
  823. private Bone GetDeviceFeatureValueOrDefault(InputDevice device, InputFeatureUsage<Bone> feature)
  824. {
  825. Bone value;
  826. if (device.TryGetFeatureValue(feature, out value))
  827. {
  828. return value;
  829. }
  830. #if UNITY_EDITOR
  831. Debug.LogWarningFormat("Device {0} doesn't have Bone feature {1}. Return default value instead.", device.name, feature.name);
  832. #endif
  833. return default;
  834. }
  835. private Eyes GetDeviceFeatureValueOrDefault(InputDevice device, InputFeatureUsage<Eyes> feature)
  836. {
  837. Eyes value;
  838. if (device.TryGetFeatureValue(feature, out value))
  839. {
  840. return value;
  841. }
  842. #if UNITY_EDITOR
  843. Debug.LogWarningFormat("Device {0} doesn't have Eyes feature {1}. Return default value instead.", device.name, feature.name);
  844. #endif
  845. return default;
  846. }
  847. private InputTrackingState GetDeviceFeatureValueOrDefault(InputDevice device, InputFeatureUsage<InputTrackingState> feature)
  848. {
  849. InputTrackingState value;
  850. if (device.TryGetFeatureValue(feature, out value))
  851. {
  852. return value;
  853. }
  854. #if UNITY_EDITOR
  855. Debug.LogWarningFormat("Device {0} doesn't have InputTrackingState feature {1}. Return default value instead.", device.name, feature.name);
  856. #endif
  857. return default;
  858. }
  859. private void LogDeviceFeatureUsages(InputDevice device)
  860. {
  861. List<InputFeatureUsage> usages = new List<InputFeatureUsage>();
  862. if (device.TryGetFeatureUsages(usages))
  863. {
  864. string strUsages = "";
  865. foreach (var usage in usages)
  866. {
  867. strUsages += "[" + usage.type.Name + "] " + usage.name + "\n";
  868. }
  869. Debug.Log(device.name + " feature usages:\n\n" + strUsages);
  870. }
  871. }
  872. private static string CharacteristicsToString(InputDeviceCharacteristics ch)
  873. {
  874. if (ch == 0u) { return " No Characteristic"; }
  875. var chu = (uint)ch;
  876. var str = string.Empty;
  877. for (var i = 1u; chu > 0u; i <<= 1)
  878. {
  879. if ((chu & i) == 0u) { continue; }
  880. str += " " + (InputDeviceCharacteristics)i;
  881. chu &= ~i;
  882. }
  883. return str;
  884. }
  885. #endif
  886. }
  887. }