LeapServiceProvider.cs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. using System;
  2. using System.Collections;
  3. using Leap.Unity.Attributes;
  4. using UnityEngine;
  5. namespace Leap.Unity
  6. {
  7. public class LeapServiceProvider : LeapProvider
  8. {
  9. public override Frame CurrentFrame
  10. {
  11. get
  12. {
  13. return this._transformedUpdateFrame;
  14. }
  15. }
  16. public override Image CurrentImage
  17. {
  18. get
  19. {
  20. return this._currentImage;
  21. }
  22. }
  23. public override Frame CurrentFixedFrame
  24. {
  25. get
  26. {
  27. if (this._reuseFramesForPhysics)
  28. {
  29. return this._transformedUpdateFrame;
  30. }
  31. return this._transformedFixedFrame;
  32. }
  33. }
  34. public bool UseInterpolation
  35. {
  36. get
  37. {
  38. return this._useInterpolation;
  39. }
  40. set
  41. {
  42. this._useInterpolation = value;
  43. }
  44. }
  45. public long InterpolationDelay
  46. {
  47. get
  48. {
  49. return this._interpolationDelay;
  50. }
  51. set
  52. {
  53. this._interpolationDelay = value;
  54. }
  55. }
  56. public Controller GetLeapController()
  57. {
  58. return this.leap_controller_;
  59. }
  60. public bool IsConnected()
  61. {
  62. return this.GetLeapController().IsConnected;
  63. }
  64. public LeapDeviceInfo GetDeviceInfo()
  65. {
  66. if (this._overrideDeviceType)
  67. {
  68. return new LeapDeviceInfo(this._overrideDeviceTypeWith);
  69. }
  70. DeviceList devices = this.GetLeapController().Devices;
  71. if (devices.Count == 1)
  72. {
  73. LeapDeviceInfo result = new LeapDeviceInfo(LeapDeviceType.Peripheral);
  74. if (devices[0].SerialNumber.Length >= 2)
  75. {
  76. string text = devices[0].SerialNumber.Substring(0, 2);
  77. if (text != null)
  78. {
  79. if (!(text == "LP"))
  80. {
  81. if (text == "LE")
  82. {
  83. result = new LeapDeviceInfo(LeapDeviceType.Dragonfly);
  84. }
  85. }
  86. else
  87. {
  88. result = new LeapDeviceInfo(LeapDeviceType.Peripheral);
  89. }
  90. }
  91. }
  92. result.isEmbedded = devices[0].IsEmbedded;
  93. result.horizontalViewAngle = devices[0].HorizontalViewAngle * 57.29578f;
  94. result.verticalViewAngle = devices[0].VerticalViewAngle * 57.29578f;
  95. result.trackingRange = devices[0].Range / 1000f;
  96. result.serialID = devices[0].SerialNumber;
  97. return result;
  98. }
  99. if (devices.Count > 1)
  100. {
  101. return new LeapDeviceInfo(LeapDeviceType.Peripheral);
  102. }
  103. return new LeapDeviceInfo(LeapDeviceType.Invalid);
  104. }
  105. public void ReTransformFrames()
  106. {
  107. this.transformFrame(this._untransformedUpdateFrame, this._transformedUpdateFrame);
  108. this.transformFrame(this._untransformedFixedFrame, this._transformedFixedFrame);
  109. }
  110. protected virtual void Awake()
  111. {
  112. this.clockCorrelator = new ClockCorrelator();
  113. this._fixedOffset.delay = 0.4f;
  114. }
  115. protected virtual void Start()
  116. {
  117. this.createController();
  118. this._transformedUpdateFrame = new Frame();
  119. this._transformedFixedFrame = new Frame();
  120. this._untransformedUpdateFrame = new Frame();
  121. this._untransformedFixedFrame = new Frame();
  122. base.StartCoroutine(this.waitCoroutine());
  123. }
  124. protected IEnumerator waitCoroutine()
  125. {
  126. WaitForEndOfFrame endWaiter = new WaitForEndOfFrame();
  127. for (;;)
  128. {
  129. yield return endWaiter;
  130. long unityTime = (long)((double)Time.time * 1000000.0);
  131. this.clockCorrelator.UpdateRebaseEstimate(unityTime);
  132. }
  133. yield break;
  134. }
  135. protected virtual void Update()
  136. {
  137. this._fixedOffset.Update(Time.time - Time.fixedTime, Time.deltaTime);
  138. if (this._useInterpolation)
  139. {
  140. long num = (long)((double)Time.time * 1000000.0);
  141. long applicationClock = num - this._interpolationDelay * 1000L;
  142. long time = this.clockCorrelator.ExternalClockToLeapTime(applicationClock);
  143. this.leap_controller_.GetInterpolatedFrame(this._untransformedUpdateFrame, time);
  144. }
  145. else
  146. {
  147. this.leap_controller_.Frame(this._untransformedUpdateFrame);
  148. }
  149. if (this._untransformedUpdateFrame != null)
  150. {
  151. this.transformFrame(this._untransformedUpdateFrame, this._transformedUpdateFrame);
  152. base.DispatchUpdateFrameEvent(this._transformedUpdateFrame);
  153. }
  154. }
  155. protected virtual void FixedUpdate()
  156. {
  157. if (this._reuseFramesForPhysics)
  158. {
  159. base.DispatchFixedFrameEvent(this._transformedUpdateFrame);
  160. return;
  161. }
  162. if (this._useInterpolation)
  163. {
  164. long num = (long)((double)(Time.fixedTime + this._fixedOffset.value) * 1000000.0);
  165. long applicationClock = num - this._interpolationDelay * 1000L;
  166. long time = this.clockCorrelator.ExternalClockToLeapTime(applicationClock);
  167. this.leap_controller_.GetInterpolatedFrame(this._untransformedFixedFrame, time);
  168. }
  169. else
  170. {
  171. this.leap_controller_.Frame(this._untransformedFixedFrame);
  172. }
  173. if (this._untransformedFixedFrame != null)
  174. {
  175. this.transformFrame(this._untransformedFixedFrame, this._transformedFixedFrame);
  176. base.DispatchFixedFrameEvent(this._transformedFixedFrame);
  177. }
  178. }
  179. protected virtual void OnDestroy()
  180. {
  181. this.destroyController();
  182. }
  183. protected virtual void OnApplicationPause(bool isPaused)
  184. {
  185. if (this.leap_controller_ != null)
  186. {
  187. if (isPaused)
  188. {
  189. this.leap_controller_.StopConnection();
  190. }
  191. else
  192. {
  193. this.leap_controller_.StartConnection();
  194. }
  195. }
  196. }
  197. protected virtual void OnApplicationQuit()
  198. {
  199. this.destroyController();
  200. }
  201. protected void initializeFlags()
  202. {
  203. if (this.leap_controller_ == null)
  204. {
  205. return;
  206. }
  207. if (this._isHeadMounted)
  208. {
  209. this.leap_controller_.SetPolicy(Controller.PolicyFlag.POLICY_OPTIMIZE_HMD);
  210. }
  211. else
  212. {
  213. this.leap_controller_.ClearPolicy(Controller.PolicyFlag.POLICY_OPTIMIZE_HMD);
  214. }
  215. }
  216. protected void createController()
  217. {
  218. if (this.leap_controller_ != null)
  219. {
  220. this.destroyController();
  221. }
  222. this.leap_controller_ = new Controller();
  223. if (this.leap_controller_.IsConnected)
  224. {
  225. this.initializeFlags();
  226. }
  227. else
  228. {
  229. this.leap_controller_.Device += new EventHandler<DeviceEventArgs>(this.onHandControllerConnect);
  230. }
  231. }
  232. protected void destroyController()
  233. {
  234. if (this.leap_controller_ != null)
  235. {
  236. if (this.leap_controller_.IsConnected)
  237. {
  238. this.leap_controller_.ClearPolicy(Controller.PolicyFlag.POLICY_OPTIMIZE_HMD);
  239. }
  240. this.leap_controller_.StopConnection();
  241. this.leap_controller_ = null;
  242. }
  243. }
  244. protected void onHandControllerConnect(object sender, LeapEventArgs args)
  245. {
  246. this.initializeFlags();
  247. this.leap_controller_.Device -= new EventHandler<DeviceEventArgs>(this.onHandControllerConnect);
  248. }
  249. protected void transformFrame(Frame source, Frame dest)
  250. {
  251. LeapTransform leapMatrix;
  252. if (this._temporalWarping != null)
  253. {
  254. Vector3 vector;
  255. Quaternion quaternion;
  256. this._temporalWarping.TryGetWarpedTransform(LeapVRTemporalWarping.WarpedAnchor.CENTER, out vector, out quaternion, source.Timestamp);
  257. quaternion *= base.transform.localRotation;
  258. leapMatrix = new LeapTransform(vector.ToVector(), quaternion.ToLeapQuaternion(), base.transform.lossyScale.ToVector() * 0.001f);
  259. leapMatrix.MirrorZ();
  260. }
  261. else
  262. {
  263. leapMatrix = base.transform.GetLeapMatrix();
  264. }
  265. dest.CopyFrom(source).Transform(leapMatrix);
  266. }
  267. protected const float NS_TO_S = 1E-06f;
  268. protected const float S_TO_NS = 1000000f;
  269. protected const float FIXED_UPDATE_OFFSET_SMOOTHING_DELAY = 0.1f;
  270. [Tooltip("Set true if the Leap Motion hardware is mounted on an HMD; otherwise, leave false.")]
  271. [SerializeField]
  272. protected bool _isHeadMounted;
  273. [AutoFind(AutoFindLocations.All)]
  274. [SerializeField]
  275. protected LeapVRTemporalWarping _temporalWarping;
  276. [Tooltip("When true, update frames will be re-used for physics. This is an optimization, since the total number of frames that need to be calculated is halved. However, this introduces extra latency and inaccuracy into the physics frames.")]
  277. [SerializeField]
  278. protected bool _reuseFramesForPhysics;
  279. [Header("Device Type")]
  280. [SerializeField]
  281. protected bool _overrideDeviceType;
  282. [Tooltip("If overrideDeviceType is enabled, the hand controller will return a device of this type.")]
  283. [SerializeField]
  284. protected LeapDeviceType _overrideDeviceTypeWith = LeapDeviceType.Peripheral;
  285. [Header("Interpolation")]
  286. [Tooltip("Interpolate frames to deliver a potentially smoother experience. Currently experimental.")]
  287. [SerializeField]
  288. protected bool _useInterpolation;
  289. [Tooltip("How much delay should be added to interpolation. A non-zero amount is needed to prevent extrapolation artifacts.")]
  290. [SerializeField]
  291. protected long _interpolationDelay = 15L;
  292. protected Controller leap_controller_;
  293. protected SmoothedFloat _fixedOffset = new SmoothedFloat();
  294. protected Frame _untransformedUpdateFrame;
  295. protected Frame _transformedUpdateFrame;
  296. protected Frame _untransformedFixedFrame;
  297. protected Frame _transformedFixedFrame;
  298. protected Image _currentImage;
  299. private ClockCorrelator clockCorrelator;
  300. }
  301. }