Assignment for RMIT Mixed Reality in 2020
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.

128 lines
5.1 KiB

  1. // Copyright (c) Microsoft Corporation. All rights reserved.
  2. // Licensed under the MIT License. See LICENSE in the project root for license information.
  3. //
  4. // ###
  5. // # Kindly borrowed and extended from Microsoft MRTK (https://github.com/Microsoft/MixedRealityToolkit-Unity) to work with VRTK.
  6. // ###
  7. #if UNITY_WSA
  8. #if !UNITY_2017_2_OR_NEWER
  9. using UnityEngine.VR.WSA.Input;
  10. #else
  11. using UnityEngine.XR.WSA.Input;
  12. #if !UNITY_EDITOR
  13. using System;
  14. using System.Collections.Generic;
  15. using Windows.Devices.Haptics;
  16. using Windows.Foundation;
  17. using Windows.Perception;
  18. using Windows.Storage.Streams;
  19. using Windows.UI.Input.Spatial;
  20. #endif
  21. #endif
  22. #endif
  23. namespace VRTK.WindowsMixedReality.Utilities
  24. {
  25. /// <summary>
  26. /// Extensions for the InteractionSource class to add haptics and expose the renderable model.
  27. /// </summary>
  28. public static class InteractionSourceExtensions
  29. {
  30. // This value is standardized according to www.usb.org/developers/hidpage/HUTRR63b_-_Haptics_Page_Redline.pdf
  31. private const ushort ContinuousBuzzWaveform = 0x1004;
  32. #if UNITY_WSA
  33. public static void StartHaptics(this InteractionSource interactionSource, float intensity)
  34. {
  35. interactionSource.StartHaptics(intensity, float.MaxValue);
  36. }
  37. public static void StartHaptics(this InteractionSource interactionSource, float intensity, float durationInSeconds)
  38. {
  39. if (!WindowsApiChecker.UniversalApiContractV4_IsAvailable)
  40. {
  41. return;
  42. }
  43. #if !UNITY_EDITOR && UNITY_2017_2_OR_NEWER
  44. UnityEngine.WSA.Application.InvokeOnUIThread(() =>
  45. {
  46. IReadOnlyList<SpatialInteractionSourceState> sources = SpatialInteractionManager.GetForCurrentView().GetDetectedSourcesAtTimestamp(PerceptionTimestampHelper.FromHistoricalTargetTime(DateTimeOffset.Now));
  47. foreach (SpatialInteractionSourceState sourceState in sources)
  48. {
  49. if (sourceState.Source.Id.Equals(interactionSource.id))
  50. {
  51. SimpleHapticsController simpleHapticsController = sourceState.Source.Controller.SimpleHapticsController;
  52. foreach (SimpleHapticsControllerFeedback hapticsFeedback in simpleHapticsController.SupportedFeedback)
  53. {
  54. if (hapticsFeedback.Waveform.Equals(ContinuousBuzzWaveform))
  55. {
  56. if (durationInSeconds.Equals(float.MaxValue))
  57. {
  58. simpleHapticsController.SendHapticFeedback(hapticsFeedback, intensity);
  59. }
  60. else
  61. {
  62. simpleHapticsController.SendHapticFeedbackForDuration(hapticsFeedback, intensity, TimeSpan.FromSeconds(durationInSeconds));
  63. }
  64. return;
  65. }
  66. }
  67. }
  68. }
  69. }, true);
  70. #endif
  71. }
  72. public static void StopHaptics(this InteractionSource interactionSource)
  73. {
  74. if (!WindowsApiChecker.UniversalApiContractV4_IsAvailable)
  75. {
  76. return;
  77. }
  78. #if !UNITY_EDITOR && UNITY_2017_2_OR_NEWER
  79. UnityEngine.WSA.Application.InvokeOnUIThread(() =>
  80. {
  81. IReadOnlyList<SpatialInteractionSourceState> sources = SpatialInteractionManager.GetForCurrentView().GetDetectedSourcesAtTimestamp(PerceptionTimestampHelper.FromHistoricalTargetTime(DateTimeOffset.Now));
  82. foreach (SpatialInteractionSourceState sourceState in sources)
  83. {
  84. if (sourceState.Source.Id.Equals(interactionSource.id))
  85. {
  86. sourceState.Source.Controller.SimpleHapticsController.StopFeedback();
  87. }
  88. }
  89. }, true);
  90. #endif
  91. }
  92. #if !UNITY_EDITOR && UNITY_2017_2_OR_NEWER
  93. public static IAsyncOperation<IRandomAccessStreamWithContentType> TryGetRenderableModelAsync(this InteractionSource interactionSource)
  94. {
  95. IAsyncOperation<IRandomAccessStreamWithContentType> returnValue = null;
  96. if (WindowsApiChecker.UniversalApiContractV5_IsAvailable)
  97. {
  98. UnityEngine.WSA.Application.InvokeOnUIThread(() =>
  99. {
  100. IReadOnlyList<SpatialInteractionSourceState> sources = SpatialInteractionManager.GetForCurrentView().GetDetectedSourcesAtTimestamp(PerceptionTimestampHelper.FromHistoricalTargetTime(DateTimeOffset.Now));
  101. foreach (SpatialInteractionSourceState sourceState in sources)
  102. {
  103. if (sourceState.Source.Id.Equals(interactionSource.id))
  104. {
  105. returnValue = sourceState.Source.Controller.TryGetRenderableModelAsync();
  106. }
  107. }
  108. }, true);
  109. }
  110. return returnValue;
  111. }
  112. #endif
  113. #endif
  114. }
  115. }