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.

636 lines
30 KiB

  1. // WindowsMR Controller|SDK_WindowsMR|004
  2. namespace VRTK
  3. {
  4. using UnityEngine;
  5. using System.Collections.Generic;
  6. #if VRTK_DEFINE_SDK_WINDOWSMR && UNITY_2017_2_OR_NEWER
  7. using UnityEngine.XR.WSA.Input;
  8. #endif
  9. #if VRTK_DEFINE_WINDOWSMR_CONTROLLER_VISUALIZATION
  10. using VRTK.WindowsMixedReality;
  11. #endif
  12. /// <summary>
  13. /// The WindowsMR Controller SDK script provides a bridge to SDK methods that deal with the input devices.
  14. /// </summary>
  15. [SDK_Description(typeof(SDK_WindowsMR))]
  16. public class SDK_WindowsMRController
  17. #if VRTK_DEFINE_SDK_WINDOWSMR && UNITY_2017_2_OR_NEWER
  18. : SDK_BaseController
  19. #else
  20. : SDK_FallbackController
  21. #endif
  22. {
  23. #if VRTK_DEFINE_SDK_WINDOWSMR && UNITY_2017_2_OR_NEWER
  24. protected WindowsMR_TrackedObject cachedLeftTrackedObject;
  25. protected WindowsMR_TrackedObject cachedRightTrackedObject;
  26. protected VRTK_VelocityEstimator cachedLeftVelocityEstimator;
  27. protected VRTK_VelocityEstimator cachedRightVelocityEstimator;
  28. protected Dictionary<GameObject, WindowsMR_TrackedObject> cachedTrackedObjectsByGameObject = new Dictionary<GameObject, WindowsMR_TrackedObject>();
  29. protected Dictionary<uint, WindowsMR_TrackedObject> cachedTrackedObjectsByIndex = new Dictionary<uint, WindowsMR_TrackedObject>();
  30. #region Overriden base functions
  31. /// <summary>
  32. /// The GenerateControllerPointerOrigin method can create a custom pointer origin Transform to represent the pointer position and forward.
  33. /// </summary>
  34. /// <param name="parent">The GameObject that the origin will become parent of. If it is a controller then it will also be used to determine the hand if required.</param>
  35. /// <returns>A generated Transform that contains the custom pointer origin.</returns>
  36. [System.Obsolete("GenerateControllerPointerOrigin has been deprecated and will be removed in a future version of VRTK.")]
  37. public override Transform GenerateControllerPointerOrigin(GameObject parent)
  38. {
  39. //TODO: Implement
  40. return null;
  41. }
  42. /// <summary>
  43. /// The GetAngularVelocity method is used to determine the current angular velocity of the tracked object on the given controller reference.
  44. /// </summary>
  45. /// <param name="controllerReference">The reference to the tracked object to check for.</param>
  46. /// <returns>A Vector3 containing the current angular velocity of the tracked object.</returns>
  47. public override Vector3 GetAngularVelocity(VRTK_ControllerReference controllerReference)
  48. {
  49. if (VRTK_ControllerReference.IsValid(controllerReference))
  50. {
  51. if (controllerReference.hand == ControllerHand.Left && cachedLeftVelocityEstimator != null)
  52. {
  53. return cachedLeftVelocityEstimator.GetAngularVelocityEstimate();
  54. }
  55. else if (controllerReference.hand == ControllerHand.Right && cachedRightVelocityEstimator != null)
  56. {
  57. return cachedRightVelocityEstimator.GetAngularVelocityEstimate();
  58. }
  59. }
  60. return Vector3.zero;
  61. }
  62. /// <summary>
  63. /// The GetButtonAxis method retrieves the current X/Y axis values for the given button type on the given controller reference.
  64. /// </summary>
  65. /// <param name="buttonType">The type of button to check for the axis on.</param>
  66. /// <param name="controllerReference">The reference to the controller to check the button axis on.</param>
  67. /// <returns>A Vector2 of the X/Y values of the button axis. If no axis values exist for the given button, then a Vector2.Zero is returned.</returns>
  68. public override Vector2 GetButtonAxis(ButtonTypes buttonType, VRTK_ControllerReference controllerReference)
  69. {
  70. uint index = VRTK_ControllerReference.GetRealIndex(controllerReference);
  71. if (GetControllerByIndex(index, true) == null)
  72. {
  73. return Vector2.zero;
  74. }
  75. WindowsMR_TrackedObject device = GetControllerByIndex(index, true).GetComponent<WindowsMR_TrackedObject>();
  76. switch (buttonType)
  77. {
  78. case ButtonTypes.Trigger:
  79. return device.GetAxis(InteractionSourcePressType.Select);
  80. case ButtonTypes.Touchpad:
  81. return device.GetAxis(InteractionSourcePressType.Touchpad);
  82. case ButtonTypes.TouchpadTwo:
  83. return device.GetAxis(InteractionSourcePressType.Thumbstick);
  84. }
  85. return Vector2.zero;
  86. }
  87. /// <summary>
  88. /// The GetButtonSenseAxis method retrieves the current sense axis value for the given button type on the given controller reference.
  89. /// </summary>
  90. /// <param name="buttonType">The type of button to check for the sense axis on.</param>
  91. /// <param name="controllerReference">The reference to the controller to check the sense axis on.</param>
  92. /// <returns>The current sense axis value.</returns>
  93. public override float GetButtonSenseAxis(ButtonTypes buttonType, VRTK_ControllerReference controllerReference)
  94. {
  95. // TODO: Implement
  96. return 0f;
  97. }
  98. /// <summary>
  99. /// The GetButtonHairlineDelta method is used to get the difference between the current button press and the previous frame button press.
  100. /// </summary>
  101. /// <param name="buttonType">The type of button to get the hairline delta for.</param>
  102. /// <param name="controllerReference">The reference to the controller to get the hairline delta for.</param>
  103. /// <returns>The delta between the button presses.</returns>
  104. public override float GetButtonHairlineDelta(ButtonTypes buttonType, VRTK_ControllerReference controllerReference)
  105. {
  106. //TODO: Implement
  107. return 0;
  108. }
  109. /// <summary>
  110. /// The GetControllerButtonState method is used to determine if the given controller button for the given press type on the given controller reference is currently taking place.
  111. /// </summary>
  112. /// <param name="buttonType">The type of button to check for the state of.</param>
  113. /// <param name="pressType">The button state to check for.</param>
  114. /// <param name="controllerReference">The reference to the controller to check the button state on.</param>
  115. /// <returns>Returns true if the given button is in the state of the given press type on the given controller reference.</returns>
  116. public override bool GetControllerButtonState(ButtonTypes buttonType, ButtonPressTypes pressType, VRTK_ControllerReference controllerReference)
  117. {
  118. if (!VRTK_ControllerReference.IsValid(controllerReference))
  119. {
  120. return false;
  121. }
  122. uint index = VRTK_ControllerReference.GetRealIndex(controllerReference);
  123. switch (buttonType)
  124. {
  125. case ButtonTypes.Trigger:
  126. return IsButtonPressed(index, pressType, InteractionSourcePressType.Select);
  127. case ButtonTypes.TriggerHairline:
  128. WindowsMR_TrackedObject device = GetControllerByIndex(index, true).GetComponent<WindowsMR_TrackedObject>();
  129. if (pressType == ButtonPressTypes.PressDown)
  130. {
  131. return device.GetHairTriggerDown();
  132. }
  133. else if (pressType == ButtonPressTypes.PressUp)
  134. {
  135. return device.GetHairTriggerUp();
  136. }
  137. break;
  138. case ButtonTypes.Grip:
  139. return IsButtonPressed(index, pressType, InteractionSourcePressType.Grasp);
  140. case ButtonTypes.Touchpad:
  141. return IsButtonPressed(index, pressType, InteractionSourcePressType.Touchpad);
  142. case ButtonTypes.TouchpadTwo:
  143. return IsButtonPressed(index, pressType, InteractionSourcePressType.Thumbstick);
  144. case ButtonTypes.ButtonTwo:
  145. case ButtonTypes.StartMenu:
  146. return IsButtonPressed(index, pressType, InteractionSourcePressType.Menu);
  147. }
  148. return false;
  149. }
  150. /// <summary>
  151. /// The GetControllerByIndex method returns the GameObject of a controller with a specific index.
  152. /// </summary>
  153. /// <param name="index">The index of the controller to find.</param>
  154. /// <param name="actual">If true it will return the actual controller, if false it will return the script alias controller GameObject.</param>
  155. /// <returns>The GameObject of the controller</returns>
  156. public override GameObject GetControllerByIndex(uint index, bool actual = false)
  157. {
  158. SetTrackedControllerCaches();
  159. if (index < uint.MaxValue)
  160. {
  161. VRTK_SDKManager sdkManager = VRTK_SDKManager.instance;
  162. if (sdkManager != null)
  163. {
  164. if (cachedLeftTrackedObject != null && (uint)cachedLeftTrackedObject.Index == index)
  165. {
  166. return (actual ? sdkManager.loadedSetup.actualLeftController : sdkManager.scriptAliasLeftController);
  167. }
  168. if (cachedRightTrackedObject != null && (uint)cachedRightTrackedObject.Index == index)
  169. {
  170. return (actual ? sdkManager.loadedSetup.actualRightController : sdkManager.scriptAliasRightController);
  171. }
  172. }
  173. if (cachedTrackedObjectsByIndex.ContainsKey(index) && cachedTrackedObjectsByIndex[index] != null)
  174. {
  175. return cachedTrackedObjectsByIndex[index].gameObject;
  176. }
  177. }
  178. return null;
  179. }
  180. /// <summary>
  181. /// The GetControllerDefaultColliderPath returns the path to the prefab that contains the collider objects for the default controller of this SDK.
  182. /// </summary>
  183. /// <param name="hand">The controller hand to check for</param>
  184. /// <returns>A path to the resource that contains the collider GameObject.</returns>
  185. public override string GetControllerDefaultColliderPath(ControllerHand hand)
  186. {
  187. //TODO: Implement
  188. return "ControllerColliders/Fallback";
  189. }
  190. /// <summary>
  191. /// The GetControllerElementPath returns the path to the game object that the given controller element for the given hand resides in.
  192. /// </summary>
  193. /// <param name="element">The controller element to look up.</param>
  194. /// <param name="hand">The controller hand to look up.</param>
  195. /// <param name="fullPath">Whether to get the initial path or the full path to the element.</param>
  196. /// <returns>A string containing the path to the game object that the controller element resides in.</returns>
  197. public override string GetControllerElementPath(ControllerElements element, ControllerHand hand, bool fullPath = false)
  198. {
  199. #if VRTK_DEFINE_WINDOWSMR_CONTROLLER_VISUALIZATION
  200. InteractionSourceHandedness handedness;
  201. switch (hand)
  202. {
  203. case ControllerHand.Left:
  204. handedness = InteractionSourceHandedness.Left;
  205. break;
  206. case ControllerHand.Right:
  207. handedness = InteractionSourceHandedness.Right;
  208. break;
  209. default:
  210. handedness = InteractionSourceHandedness.Unknown;
  211. break;
  212. }
  213. return MotionControllerVisualizer.Instance.GetPathToButton(element, handedness);
  214. #else
  215. return "";
  216. #endif
  217. }
  218. /// <summary>
  219. /// The GetControllerIndex method returns the index of the given controller.
  220. /// </summary>
  221. /// <param name="controller">The GameObject containing the controller.</param>
  222. /// <returns>The index of the given controller.</returns>
  223. public override uint GetControllerIndex(GameObject controller)
  224. {
  225. WindowsMR_TrackedObject trackedObject = GetTrackedObject(controller);
  226. return (trackedObject != null ? (uint)trackedObject.Index : uint.MaxValue);
  227. }
  228. /// <summary>
  229. /// The GetControllerLeftHand method returns the GameObject containing the representation of the left hand controller.
  230. /// </summary>
  231. /// <param name="actual">If true it will return the actual controller, if false it will return the script alias controller GameObject.</param>
  232. /// <returns>The GameObject containing the left hand controller.</returns>
  233. public override GameObject GetControllerLeftHand(bool actual = false)
  234. {
  235. GameObject controller = GetSDKManagerControllerLeftHand(actual);
  236. if (controller == null && actual)
  237. {
  238. controller = VRTK_SharedMethods.FindEvenInactiveGameObject<WindowsMR_ControllerManager>("Controller (left)");
  239. }
  240. return controller;
  241. }
  242. /// <summary>
  243. /// The GetControllerModel method returns the model alias for the given GameObject.
  244. /// </summary>
  245. /// <param name="controller">The GameObject to get the model alias for.</param>
  246. /// <returns>The GameObject that has the model alias within it.</returns>
  247. public override GameObject GetControllerModel(GameObject controller)
  248. {
  249. return GetControllerModelFromController(controller);
  250. }
  251. /// <summary>
  252. /// The GetControllerModel method returns the model alias for the given controller hand.
  253. /// </summary>
  254. /// <param name="hand">The hand enum of which controller model to retrieve.</param>
  255. /// <returns>The GameObject that has the model alias within it.</returns>
  256. public override GameObject GetControllerModel(ControllerHand hand)
  257. {
  258. GameObject model = GetSDKManagerControllerModelForHand(hand);
  259. if (model == null)
  260. {
  261. GameObject controller = null;
  262. switch (hand)
  263. {
  264. case ControllerHand.Left:
  265. controller = GetControllerLeftHand(true);
  266. if (controller != null)
  267. {
  268. Transform modelTransform = controller.transform.Find("LeftControllerModel");
  269. if (modelTransform != null)
  270. {
  271. model = modelTransform.gameObject;
  272. }
  273. }
  274. break;
  275. case ControllerHand.Right:
  276. controller = GetControllerRightHand(true);
  277. if (controller != null)
  278. {
  279. Transform modelTransform = controller.transform.Find("RightControllerModel");
  280. if (modelTransform != null)
  281. {
  282. model = modelTransform.gameObject;
  283. }
  284. }
  285. break;
  286. }
  287. }
  288. return model;
  289. }
  290. /// <summary>
  291. /// The GetControllerOrigin method returns the origin of the given controller.
  292. /// </summary>
  293. /// <param name="controllerReference">The reference to the controller to retrieve the origin from.</param>
  294. /// <returns>A Transform containing the origin of the controller.</returns>
  295. public override Transform GetControllerOrigin(VRTK_ControllerReference controllerReference)
  296. {
  297. return VRTK_SDK_Bridge.GetPlayArea();
  298. }
  299. /// <summary>
  300. /// The GetControllerRenderModel method gets the game object that contains the given controller's render model.
  301. /// </summary>
  302. /// <param name="controllerReference">The reference to the controller to check.</param>
  303. /// <returns>A GameObject containing the object that has a render model for the controller.</returns>
  304. public override GameObject GetControllerRenderModel(VRTK_ControllerReference controllerReference)
  305. {
  306. return null;
  307. }
  308. /// <summary>
  309. /// The GetControllerRightHand method returns the GameObject containing the representation of the right hand controller.
  310. /// </summary>
  311. /// <param name="actual">If true it will return the actual controller, if false it will return the script alias controller GameObject.</param>
  312. /// <returns>The GameObject containing the right hand controller.</returns>
  313. public override GameObject GetControllerRightHand(bool actual = false)
  314. {
  315. GameObject controller = GetSDKManagerControllerRightHand(actual);
  316. if (controller == null && actual)
  317. {
  318. controller = VRTK_SharedMethods.FindEvenInactiveGameObject<WindowsMR_ControllerManager>("Controller (right)");
  319. }
  320. return controller;
  321. }
  322. /// <summary>
  323. /// The GetCurrentControllerType method returns the current used ControllerType based on the SDK and headset being used.
  324. /// </summary>
  325. /// <returns>The ControllerType based on the SDK and headset being used.</returns>
  326. public override ControllerType GetCurrentControllerType(VRTK_ControllerReference controllerReference = null)
  327. {
  328. return ControllerType.WindowsMR_MotionController;
  329. }
  330. /// <summary>
  331. /// The GetHapticModifiers method is used to return modifiers for the duration and interval if the SDK handles it slightly differently.
  332. /// </summary>
  333. /// <returns>An SDK_ControllerHapticModifiers object with a given `durationModifier` and an `intervalModifier`.</returns>
  334. public override SDK_ControllerHapticModifiers GetHapticModifiers()
  335. {
  336. SDK_ControllerHapticModifiers modifiers = new SDK_ControllerHapticModifiers();
  337. modifiers.durationModifier = 0.4f;
  338. return modifiers;
  339. }
  340. /// <summary>
  341. /// The GetVelocity method is used to determine the current velocity of the tracked object on the given controller reference.
  342. /// </summary>
  343. /// <param name="controllerReference">The reference to the tracked object to check for.</param>
  344. /// <returns>A Vector3 containing the current velocity of the tracked object.</returns>
  345. public override Vector3 GetVelocity(VRTK_ControllerReference controllerReference)
  346. {
  347. if (VRTK_ControllerReference.IsValid(controllerReference))
  348. {
  349. if (controllerReference.hand == ControllerHand.Left && cachedLeftVelocityEstimator != null)
  350. {
  351. return cachedLeftVelocityEstimator.GetVelocityEstimate();
  352. }
  353. else if (controllerReference.hand == ControllerHand.Right && cachedRightVelocityEstimator != null)
  354. {
  355. return cachedRightVelocityEstimator.GetVelocityEstimate();
  356. }
  357. }
  358. return Vector3.zero;
  359. }
  360. /// <summary>
  361. /// The HapticPulse/2 method is used to initiate a simple haptic pulse on the tracked object of the given controller reference.
  362. /// </summary>
  363. /// <param name="controllerReference">The reference to the tracked object to initiate the haptic pulse on.</param>
  364. /// <param name="strength">The intensity of the rumble of the controller motor. `0` to `1`.</param>
  365. public override void HapticPulse(VRTK_ControllerReference controllerReference, float strength = 0.5F)
  366. {
  367. uint index = VRTK_ControllerReference.GetRealIndex(controllerReference);
  368. WindowsMR_TrackedObject device = GetControllerByIndex(index).transform.parent.GetComponent<WindowsMR_TrackedObject>();
  369. if (device != null)
  370. {
  371. device.StartHaptics(1f, 1f);
  372. }
  373. }
  374. /// <summary>
  375. /// The HapticPulse/2 method is used to initiate a haptic pulse based on an audio clip on the tracked object of the given controller reference.
  376. /// </summary>
  377. /// <param name="controllerReference">The reference to the tracked object to initiate the haptic pulse on.</param>
  378. /// <param name="clip">The audio clip to use for the haptic pattern.</param>
  379. public override bool HapticPulse(VRTK_ControllerReference controllerReference, AudioClip clip)
  380. {
  381. return false;
  382. }
  383. /// <summary>
  384. /// The IsControllerLeftHand/1 method is used to check if the given controller is the the left hand controller.
  385. /// </summary>
  386. /// <param name="controller">The GameObject to check.</param>
  387. /// <returns>Returns true if the given controller is the left hand controller.</returns>
  388. public override bool IsControllerLeftHand(GameObject controller)
  389. {
  390. return CheckActualOrScriptAliasControllerIsLeftHand(controller);
  391. }
  392. /// <summary>
  393. /// The IsControllerLeftHand/2 method is used to check if the given controller is the the left hand controller.
  394. /// </summary>
  395. /// <param name="controller">The GameObject to check.</param>
  396. /// <param name="actual">If true it will check the actual controller, if false it will check the script alias controller.</param>
  397. /// <returns>Returns true if the given controller is the left hand controller.</returns>
  398. public override bool IsControllerLeftHand(GameObject controller, bool actual)
  399. {
  400. return CheckControllerLeftHand(controller, actual);
  401. }
  402. /// <summary>
  403. /// The IsControllerRightHand/1 method is used to check if the given controller is the the right hand controller.
  404. /// </summary>
  405. /// <param name="controller">The GameObject to check.</param>
  406. /// <returns>Returns true if the given controller is the right hand controller.</returns>
  407. public override bool IsControllerRightHand(GameObject controller)
  408. {
  409. return CheckActualOrScriptAliasControllerIsRightHand(controller);
  410. }
  411. /// <summary>
  412. /// The IsControllerRightHand/2 method is used to check if the given controller is the the right hand controller.
  413. /// </summary>
  414. /// <param name="controller">The GameObject to check.</param>
  415. /// <param name="actual">If true it will check the actual controller, if false it will check the script alias controller.</param>
  416. /// <returns>Returns true if the given controller is the right hand controller.</returns>
  417. public override bool IsControllerRightHand(GameObject controller, bool actual)
  418. {
  419. return CheckControllerRightHand(controller, actual);
  420. }
  421. /// <summary>
  422. /// The IsTouchpadStatic method is used to determine if the touchpad is currently not being moved.
  423. /// </summary>
  424. /// <param name="currentAxisValues"></param>
  425. /// <param name="previousAxisValues"></param>
  426. /// <param name="compareFidelity"></param>
  427. /// <returns>Returns true if the touchpad is not currently being touched or moved.</returns>
  428. public override bool IsTouchpadStatic(bool isTouched, Vector2 currentAxisValues, Vector2 previousAxisValues, int compareFidelity)
  429. {
  430. return (!isTouched || VRTK_SharedMethods.Vector2ShallowCompare(currentAxisValues, previousAxisValues, compareFidelity));
  431. }
  432. /// <summary>
  433. /// The ProcessFixedUpdate method enables an SDK to run logic for every Unity FixedUpdate
  434. /// </summary>
  435. /// <param name="controllerReference">The reference for the controller.</param>
  436. /// <param name="options">A dictionary of generic options that can be used to within the fixed update.</param>
  437. public override void ProcessFixedUpdate(VRTK_ControllerReference controllerReference, Dictionary<string, object> options)
  438. {
  439. }
  440. /// <summary>
  441. /// The ProcessUpdate method enables an SDK to run logic for every Unity Update
  442. /// </summary>
  443. /// <param name="controllerReference">The reference for the controller.</param>
  444. /// <param name="options">A dictionary of generic options that can be used to within the update.</param>
  445. public override void ProcessUpdate(VRTK_ControllerReference controllerReference, Dictionary<string, object> options)
  446. {
  447. }
  448. /// <summary>
  449. /// The SetControllerRenderModelWheel method sets the state of the scroll wheel on the controller render model.
  450. /// </summary>
  451. /// <param name="renderModel">The GameObject containing the controller render model.</param>
  452. /// <param name="state">If true and the render model has a scroll wheen then it will be displayed, if false then the scroll wheel will be hidden.</param>
  453. public override void SetControllerRenderModelWheel(GameObject renderModel, bool state)
  454. {
  455. }
  456. /// <summary>
  457. /// The WaitForControllerModel method determines whether the controller model for the given hand requires waiting to load in on scene start.
  458. /// </summary>
  459. /// <param name="hand">The hand to determine if the controller model will be ready for.</param>
  460. /// <returns>Returns true if the controller model requires loading in at runtime and therefore needs waiting for. Returns false if the controller model will be available at start.</returns>
  461. public override bool WaitForControllerModel(ControllerHand hand)
  462. {
  463. return true;
  464. }
  465. #endregion
  466. protected virtual WindowsMR_TrackedObject GetTrackedObject(GameObject controller)
  467. {
  468. SetTrackedControllerCaches();
  469. if (IsControllerLeftHand(controller))
  470. {
  471. return cachedLeftTrackedObject;
  472. }
  473. else if (IsControllerRightHand(controller))
  474. {
  475. return cachedRightTrackedObject;
  476. }
  477. if (controller == null)
  478. {
  479. return null;
  480. }
  481. if (cachedTrackedObjectsByGameObject.ContainsKey(controller) && cachedTrackedObjectsByGameObject[controller] != null)
  482. {
  483. return cachedTrackedObjectsByGameObject[controller];
  484. }
  485. else
  486. {
  487. WindowsMR_TrackedObject trackedObject = controller.GetComponent<WindowsMR_TrackedObject>();
  488. if (trackedObject != null)
  489. {
  490. cachedTrackedObjectsByGameObject.Add(controller, trackedObject);
  491. cachedTrackedObjectsByIndex.Add((uint)trackedObject.Index, trackedObject);
  492. }
  493. return trackedObject;
  494. }
  495. }
  496. protected virtual void SetTrackedControllerCaches(bool forceRefresh = false)
  497. {
  498. if (forceRefresh)
  499. {
  500. cachedLeftTrackedObject = null;
  501. cachedRightTrackedObject = null;
  502. cachedTrackedObjectsByGameObject.Clear();
  503. cachedTrackedObjectsByIndex.Clear();
  504. }
  505. VRTK_SDKManager sdkManager = VRTK_SDKManager.instance;
  506. if (sdkManager != null)
  507. {
  508. if (cachedLeftTrackedObject == null && sdkManager.loadedSetup.actualLeftController)
  509. {
  510. cachedLeftTrackedObject = sdkManager.loadedSetup.actualLeftController.GetComponent<WindowsMR_TrackedObject>();
  511. cachedLeftVelocityEstimator = cachedLeftTrackedObject.GetComponent<VRTK_VelocityEstimator>();
  512. }
  513. if (cachedRightTrackedObject == null && sdkManager.loadedSetup.actualRightController)
  514. {
  515. cachedRightTrackedObject = sdkManager.loadedSetup.actualRightController.GetComponent<WindowsMR_TrackedObject>();
  516. cachedRightVelocityEstimator = cachedRightTrackedObject.GetComponent<VRTK_VelocityEstimator>();
  517. }
  518. }
  519. }
  520. protected virtual bool IsButtonPressed(uint index, ButtonPressTypes type, InteractionSourcePressType button)
  521. {
  522. bool actual = true;
  523. WindowsMR_TrackedObject device = GetControllerByIndex(index, actual).GetComponent<WindowsMR_TrackedObject>();
  524. switch (type)
  525. {
  526. case ButtonPressTypes.Press:
  527. return device.GetPress(button);
  528. case ButtonPressTypes.PressDown:
  529. return device.GetPressDown(button);
  530. case ButtonPressTypes.PressUp:
  531. return device.GetPressUp(button);
  532. case ButtonPressTypes.Touch:
  533. return device.GetTouch(button);
  534. case ButtonPressTypes.TouchDown:
  535. return device.GetTouchDown(button);
  536. case ButtonPressTypes.TouchUp:
  537. return device.GetTouchUp(button);
  538. }
  539. return false;
  540. }
  541. public override void OnAfterSetupLoad(VRTK_SDKSetup setup)
  542. {
  543. #if VRTK_DEFINE_WINDOWSMR_CONTROLLER_VISUALIZATION
  544. SubscribeToControllerModelLoaded();
  545. #endif
  546. }
  547. #if VRTK_DEFINE_WINDOWSMR_CONTROLLER_VISUALIZATION
  548. private void SubscribeToControllerModelLoaded()
  549. {
  550. if (MotionControllerVisualizer.Instance != null)
  551. {
  552. MotionControllerVisualizer.Instance.OnControllerModelLoaded += SetControllerModelReady;
  553. }
  554. }
  555. private void SetControllerModelReady(MotionControllerInfo motionControllerInfo)
  556. {
  557. VRTK_ControllerReference controllerReference = null;
  558. ControllerHand hand = ControllerHand.None;
  559. switch (motionControllerInfo.Handedness)
  560. {
  561. case InteractionSourceHandedness.Left:
  562. hand = ControllerHand.Left;
  563. controllerReference = VRTK_ControllerReference.GetControllerReference(GetControllerLeftHand());
  564. break;
  565. case InteractionSourceHandedness.Right:
  566. hand = ControllerHand.Right;
  567. controllerReference = VRTK_ControllerReference.GetControllerReference(GetControllerRightHand());
  568. break;
  569. }
  570. if (hand != ControllerHand.None && controllerReference != null)
  571. {
  572. OnControllerModelReady(hand, controllerReference);
  573. }
  574. }
  575. #endif
  576. #endif
  577. }
  578. }