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.

678 lines
32 KiB

  1. // Ximmerse Controller|SDK_Ximmerse|004
  2. namespace VRTK
  3. {
  4. #if VRTK_DEFINE_SDK_XIMMERSE
  5. using UnityEngine;
  6. using System.Collections.Generic;
  7. using Ximmerse.InputSystem;
  8. using Ximmerse.VR;
  9. #endif
  10. /// <summary>
  11. /// The Ximmerse Controller SDK script provides a bridge to SDK methods that deal with the input devices.
  12. /// </summary>
  13. [SDK_Description(typeof(SDK_XimmerseSystem))]
  14. [SDK_Description(typeof(SDK_XimmerseSystem), 1)]
  15. public class SDK_XimmerseController
  16. #if VRTK_DEFINE_SDK_XIMMERSE
  17. : SDK_BaseController
  18. #else
  19. : SDK_FallbackController
  20. #endif
  21. {
  22. #if VRTK_DEFINE_SDK_XIMMERSE
  23. protected TrackedObject cachedLeftTrackedObject;
  24. protected TrackedObject cachedRightTrackedObject;
  25. protected Quaternion[] previousControllerRotations = new Quaternion[2];
  26. protected Quaternion[] currentControllerRotations = new Quaternion[2];
  27. protected Vector3[] previousControllerPositions = new Vector3[2];
  28. protected Vector3[] currentControllerPositions = new Vector3[2];
  29. protected bool[] previousHairTriggerState = new bool[2];
  30. protected bool[] currentHairTriggerState = new bool[2];
  31. protected bool[] previousHairGripState = new bool[2];
  32. protected bool[] currentHairGripState = new bool[2];
  33. protected float[] hairTriggerLimit = new float[2];
  34. protected float[] hairGripLimit = new float[2];
  35. /// <summary>
  36. /// The ProcessUpdate method enables an SDK to run logic for every Unity Update
  37. /// </summary>
  38. /// <param name="controllerReference">The reference for the controller.</param>
  39. /// <param name="options">A dictionary of generic options that can be used to within the update.</param>
  40. public override void ProcessUpdate(VRTK_ControllerReference controllerReference, Dictionary<string, object> options)
  41. {
  42. if (controllerReference != null && controllerReference.IsValid())
  43. {
  44. uint index = VRTK_ControllerReference.GetRealIndex(controllerReference);
  45. TrackedObject device = GetTrackedObject(controllerReference.actual);
  46. if (device != null)
  47. {
  48. previousControllerRotations[index] = currentControllerRotations[index];
  49. currentControllerRotations[index] = device.transform.rotation;
  50. previousControllerPositions[index] = currentControllerPositions[index];
  51. currentControllerPositions[index] = device.transform.position;
  52. }
  53. UpdateHairValues(index, GetButtonAxis(ButtonTypes.Trigger, controllerReference).x, GetButtonHairlineDelta(ButtonTypes.Trigger, controllerReference), ref previousHairTriggerState[index], ref currentHairTriggerState[index], ref hairTriggerLimit[index]);
  54. UpdateHairValues(index, GetButtonAxis(ButtonTypes.Grip, controllerReference).x, GetButtonHairlineDelta(ButtonTypes.Grip, controllerReference), ref previousHairGripState[index], ref currentHairGripState[index], ref hairGripLimit[index]);
  55. }
  56. }
  57. /// <summary>
  58. /// The ProcessFixedUpdate method enables an SDK to run logic for every Unity FixedUpdate
  59. /// </summary>
  60. /// <param name="controllerReference">The reference for the controller.</param>
  61. /// <param name="options">A dictionary of generic options that can be used to within the fixed update.</param>
  62. public override void ProcessFixedUpdate(VRTK_ControllerReference controllerReference, Dictionary<string, object> options)
  63. {
  64. }
  65. /// <summary>
  66. /// The GetCurrentControllerType method returns the current used ControllerType based on the SDK and headset being used.
  67. /// </summary>
  68. /// <param name="controllerReference">The reference to the controller to get type of.</param>
  69. /// <returns>The ControllerType based on the SDK and headset being used.</returns>
  70. public override ControllerType GetCurrentControllerType(VRTK_ControllerReference controllerReference = null)
  71. {
  72. return ControllerType.Ximmerse_Flip;
  73. }
  74. /// <summary>
  75. /// The GetControllerDefaultColliderPath returns the path to the prefab that contains the collider objects for the default controller of this SDK.
  76. /// </summary>
  77. /// <param name="hand">The controller hand to check for</param>
  78. /// <returns>A path to the resource that contains the collider GameObject.</returns>
  79. public override string GetControllerDefaultColliderPath(ControllerHand hand)
  80. {
  81. return "ControllerColliders/XimmerseCobra02";
  82. }
  83. /// <summary>
  84. /// The GetControllerElementPath returns the path to the game object that the given controller element for the given hand resides in.
  85. /// </summary>
  86. /// <param name="element">The controller element to look up.</param>
  87. /// <param name="hand">The controller hand to look up.</param>
  88. /// <param name="fullPath">Whether to get the initial path or the full path to the element.</param>
  89. /// <returns>A string containing the path to the game object that the controller element resides in.</returns>
  90. public override string GetControllerElementPath(ControllerElements element, ControllerHand hand, bool fullPath = false)
  91. {
  92. string suffix = (fullPath ? "" : "");
  93. string handName = (hand == ControllerHand.Left) ? "cobra02-L" : "cobra02-R";
  94. string path = handName + "/Dummy";
  95. switch (element)
  96. {
  97. case ControllerElements.AttachPoint:
  98. return path + "/object_8";
  99. case ControllerElements.Trigger:
  100. return path + "/object_2" + suffix;
  101. case ControllerElements.GripLeft:
  102. return path + "/object_5" + suffix;
  103. case ControllerElements.GripRight:
  104. return path + "/object_4" + suffix;
  105. case ControllerElements.Touchpad:
  106. return path + "/Cylinder001" + suffix;
  107. case ControllerElements.ButtonOne:
  108. return path + "/Cylinder002" + suffix;
  109. case ControllerElements.ButtonTwo:
  110. return path + "/Cylinder003" + suffix;
  111. case ControllerElements.SystemMenu:
  112. return path + "/Cylinder003" + suffix;
  113. case ControllerElements.Body:
  114. return path + "/object_1";
  115. }
  116. return "";
  117. }
  118. /// <summary>
  119. /// The GetControllerIndex method returns the index of the given controller.
  120. /// </summary>
  121. /// <param name="controller">The GameObject containing the controller.</param>
  122. /// <returns>The index of the given controller.</returns>
  123. public override uint GetControllerIndex(GameObject controller)
  124. {
  125. TrackedObject trackedObject = GetTrackedObject(controller);
  126. if (trackedObject == null)
  127. {
  128. return uint.MaxValue;
  129. }
  130. else
  131. {
  132. switch (trackedObject.source)
  133. {
  134. case ControllerType.LeftController:
  135. return 0;
  136. case ControllerType.RightController:
  137. return 1;
  138. }
  139. }
  140. return uint.MaxValue;
  141. }
  142. /// <summary>
  143. /// The GetControllerByIndex method returns the GameObject of a controller with a specific index.
  144. /// </summary>
  145. /// <param name="index">The index of the controller to find.</param>
  146. /// <param name="actual">If true it will return the actual controller, if false it will return the script alias controller GameObject.</param>
  147. /// <returns></returns>
  148. public override GameObject GetControllerByIndex(uint index, bool actual = false)
  149. {
  150. SetTrackedControllerCaches();
  151. VRTK_SDKManager sdkManager = VRTK_SDKManager.instance;
  152. if (sdkManager != null)
  153. {
  154. if (cachedLeftTrackedObject != null && (uint)cachedLeftTrackedObject.controllerInput.handle == index)
  155. {
  156. return (actual ? sdkManager.loadedSetup.actualLeftController : sdkManager.scriptAliasLeftController);
  157. }
  158. if (cachedRightTrackedObject != null && (uint)cachedRightTrackedObject.controllerInput.handle == index)
  159. {
  160. return (actual ? sdkManager.loadedSetup.actualRightController : sdkManager.scriptAliasRightController);
  161. }
  162. }
  163. return null;
  164. }
  165. /// <summary>
  166. /// The GetControllerOrigin method returns the origin of the given controller.
  167. /// </summary>
  168. /// <param name="controllerReference">The reference to the controller to retrieve the origin from.</param>
  169. /// <returns>A Transform containing the origin of the controller.</returns>
  170. public override Transform GetControllerOrigin(VRTK_ControllerReference controllerReference)
  171. {
  172. TrackedObject trackedObject = GetTrackedObject(controllerReference.actual);
  173. if (trackedObject != null)
  174. {
  175. return trackedObject.transform ? trackedObject.transform : trackedObject.transform.parent;
  176. }
  177. return null;
  178. }
  179. /// <summary>
  180. /// The GenerateControllerPointerOrigin method can create a custom pointer origin Transform to represent the pointer position and forward.
  181. /// </summary>
  182. /// <returns>A generated Transform that contains the custom pointer origin.</returns>
  183. [System.Obsolete("GenerateControllerPointerOrigin has been deprecated and will be removed in a future version of VRTK.")]
  184. public override Transform GenerateControllerPointerOrigin(GameObject parent)
  185. {
  186. return null;
  187. }
  188. /// <summary>
  189. /// The GetControllerLeftHand method returns the GameObject containing the representation of the left hand controller.
  190. /// </summary>
  191. /// <param name="actual">If true it will return the actual controller, if false it will return the script alias controller GameObject.</param>
  192. /// <returns>The GameObject containing the left hand controller.</returns>
  193. public override GameObject GetControllerLeftHand(bool actual = false)
  194. {
  195. GameObject controller = GetSDKManagerControllerLeftHand(actual);
  196. if (controller == null && actual)
  197. {
  198. controller = VRTK_SharedMethods.FindEvenInactiveGameObject<VRContext>("TrackingSpace/LeftHandAnchor", true);
  199. }
  200. return controller;
  201. }
  202. /// <summary>
  203. /// The GetControllerRightHand method returns the GameObject containing the representation of the right hand controller.
  204. /// </summary>
  205. /// <param name="actual">If true it will return the actual controller, if false it will return the script alias controller GameObject.</param>
  206. /// <returns>The GameObject containing the right hand controller.</returns>
  207. public override GameObject GetControllerRightHand(bool actual = false)
  208. {
  209. GameObject controller = GetSDKManagerControllerRightHand(actual);
  210. if (controller == null && actual)
  211. {
  212. controller = VRTK_SharedMethods.FindEvenInactiveGameObject<VRContext>("TrackingSpace/RightHandAnchor", true);
  213. }
  214. return controller;
  215. }
  216. /// <summary>
  217. /// The IsControllerLeftHand/1 method is used to check if the given controller is the the left hand controller.
  218. /// </summary>
  219. /// <param name="controller">The GameObject to check.</param>
  220. /// <returns>Returns true if the given controller is the left hand controller.</returns>
  221. public override bool IsControllerLeftHand(GameObject controller)
  222. {
  223. return CheckActualOrScriptAliasControllerIsLeftHand(controller);
  224. }
  225. /// <summary>
  226. /// The IsControllerRightHand/1 method is used to check if the given controller is the the right hand controller.
  227. /// </summary>
  228. /// <param name="controller">The GameObject to check.</param>
  229. /// <returns>Returns true if the given controller is the right hand controller.</returns>
  230. public override bool IsControllerRightHand(GameObject controller)
  231. {
  232. return CheckActualOrScriptAliasControllerIsRightHand(controller);
  233. }
  234. /// <summary>
  235. /// The IsControllerLeftHand/2 method is used to check if the given controller is the the left hand controller.
  236. /// </summary>
  237. /// <param name="controller">The GameObject to check.</param>
  238. /// <param name="actual">If true it will check the actual controller, if false it will check the script alias controller.</param>
  239. /// <returns>Returns true if the given controller is the left hand controller.</returns>
  240. public override bool IsControllerLeftHand(GameObject controller, bool actual)
  241. {
  242. return CheckControllerLeftHand(controller, actual);
  243. }
  244. /// <summary>
  245. /// The IsControllerRightHand/2 method is used to check if the given controller is the the right hand controller.
  246. /// </summary>
  247. /// <param name="controller">The GameObject to check.</param>
  248. /// <param name="actual">If true it will check the actual controller, if false it will check the script alias controller.</param>
  249. /// <returns>Returns true if the given controller is the right hand controller.</returns>
  250. public override bool IsControllerRightHand(GameObject controller, bool actual)
  251. {
  252. return CheckControllerRightHand(controller, actual);
  253. }
  254. /// <summary>
  255. /// The WaitForControllerModel method determines whether the controller model for the given hand requires waiting to load in on scene start.
  256. /// </summary>
  257. /// <param name="hand">The hand to determine if the controller model will be ready for.</param>
  258. /// <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>
  259. public override bool WaitForControllerModel(ControllerHand hand)
  260. {
  261. return false;
  262. }
  263. /// <summary>
  264. /// The GetControllerModel method returns the model alias for the given GameObject.
  265. /// </summary>
  266. /// <param name="controller">The GameObject to get the model alias for.</param>
  267. /// <returns>The GameObject that has the model alias within it.</returns>
  268. public override GameObject GetControllerModel(GameObject controller)
  269. {
  270. return GetControllerModelFromController(controller);
  271. }
  272. /// <summary>
  273. /// The GetControllerModel method returns the model alias for the given controller hand.
  274. /// </summary>
  275. /// <param name="hand">The hand enum of which controller model to retrieve.</param>
  276. /// <returns>The GameObject that has the model alias within it.</returns>
  277. public override GameObject GetControllerModel(ControllerHand hand)
  278. {
  279. GameObject model = GetSDKManagerControllerModelForHand(hand);
  280. if (model == null)
  281. {
  282. GameObject controller = null;
  283. switch (hand)
  284. {
  285. case ControllerHand.Left:
  286. controller = GetControllerLeftHand(true);
  287. break;
  288. case ControllerHand.Right:
  289. controller = GetControllerRightHand(true);
  290. break;
  291. }
  292. if (controller != null)
  293. {
  294. model = controller;
  295. }
  296. }
  297. return model;
  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. MeshRenderer renderModel = controllerReference.actual.GetComponentInChildren<MeshRenderer>();
  307. return (renderModel != null ? renderModel.gameObject : null);
  308. }
  309. /// <summary>
  310. /// The SetControllerRenderModelWheel method sets the state of the scroll wheel on the controller render model.
  311. /// </summary>
  312. /// <param name="renderModel">The GameObject containing the controller render model.</param>
  313. /// <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>
  314. public override void SetControllerRenderModelWheel(GameObject renderModel, bool state)
  315. {
  316. }
  317. /// <summary>
  318. /// The HapticPulse/2 method is used to initiate a simple haptic pulse on the tracked object of the given controller reference.
  319. /// </summary>
  320. /// <param name="controllerReference">The reference to the tracked object to initiate the haptic pulse on.</param>
  321. /// <param name="strength">The intensity of the rumble of the controller motor. `0` to `1`.</param>
  322. public override void HapticPulse(VRTK_ControllerReference controllerReference, float strength = 0.5f)
  323. {
  324. if (VRTK_ControllerReference.IsValid(controllerReference))
  325. {
  326. uint index = VRTK_ControllerReference.GetRealIndex(controllerReference);
  327. int convertedStrength = Mathf.RoundToInt(1000f * strength);
  328. ControllerInput input = null;
  329. switch (index)
  330. {
  331. case 0:
  332. input = ControllerInputManager.instance.GetControllerInput(ControllerType.LeftController);
  333. break;
  334. case 1:
  335. input = ControllerInputManager.instance.GetControllerInput(ControllerType.RightController);
  336. break;
  337. }
  338. input.StartVibration(convertedStrength, 0.5f);
  339. }
  340. }
  341. /// <summary>
  342. /// 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.
  343. /// </summary>
  344. /// <param name="controllerReference">The reference to the tracked object to initiate the haptic pulse on.</param>
  345. /// <param name="clip">The audio clip to use for the haptic pattern.</param>
  346. public override bool HapticPulse(VRTK_ControllerReference controllerReference, AudioClip clip)
  347. {
  348. //Ximmerse doesn't support audio haptics so return false to do a fallback.
  349. return false;
  350. }
  351. /// <summary>
  352. /// The GetHapticModifiers method is used to return modifiers for the duration and interval if the SDK handles it slightly differently.
  353. /// </summary>
  354. /// <returns>An SDK_ControllerHapticModifiers object with a given `durationModifier` and an `intervalModifier`.</returns>
  355. public override SDK_ControllerHapticModifiers GetHapticModifiers()
  356. {
  357. SDK_ControllerHapticModifiers modifiers = new SDK_ControllerHapticModifiers();
  358. modifiers.durationModifier = 0.8f;
  359. modifiers.intervalModifier = 1f;
  360. return modifiers;
  361. }
  362. /// <summary>
  363. /// The GetVelocity method is used to determine the current velocity of the tracked object on the given controller reference.
  364. /// </summary>
  365. /// <param name="controllerReference">The reference to the tracked object to check for.</param>
  366. /// <returns>A Vector3 containing the current velocity of the tracked object.</returns>
  367. public override Vector3 GetVelocity(VRTK_ControllerReference controllerReference)
  368. {
  369. if (!VRTK_ControllerReference.IsValid(controllerReference))
  370. {
  371. return Vector3.zero;
  372. }
  373. uint index = VRTK_ControllerReference.GetRealIndex(controllerReference);
  374. ControllerInput device = GetControllerInputByIndex(index);
  375. if (device == null)
  376. {
  377. return Vector3.zero;
  378. }
  379. Vector3 deltaMovement = currentControllerPositions[index] - previousControllerPositions[index];
  380. deltaMovement /= Time.deltaTime;
  381. return deltaMovement;
  382. }
  383. /// <summary>
  384. /// The GetAngularVelocity method is used to determine the current angular velocity of the tracked object on the given controller reference.
  385. /// </summary>
  386. /// <param name="controllerReference">The reference to the tracked object to check for.</param>
  387. /// <returns>A Vector3 containing the current angular velocity of the tracked object.</returns>
  388. public override Vector3 GetAngularVelocity(VRTK_ControllerReference controllerReference)
  389. {
  390. if (!VRTK_ControllerReference.IsValid(controllerReference))
  391. {
  392. return Vector3.zero;
  393. }
  394. uint index = VRTK_ControllerReference.GetRealIndex(controllerReference);
  395. Quaternion deltaRotation = currentControllerRotations[index] * Quaternion.Inverse(previousControllerRotations[index]);
  396. return new Vector3(Mathf.DeltaAngle(0, deltaRotation.eulerAngles.x), Mathf.DeltaAngle(0, deltaRotation.eulerAngles.y), Mathf.DeltaAngle(0, deltaRotation.eulerAngles.z));
  397. }
  398. /// <summary>
  399. /// The IsTouchpadStatic method is used to determine if the touchpad is currently not being moved.
  400. /// </summary>
  401. /// <param name="currentAxisValues"></param>
  402. /// <param name="previousAxisValues"></param>
  403. /// <param name="compareFidelity"></param>
  404. /// <returns>Returns true if the touchpad is not currently being touched or moved.</returns>
  405. public override bool IsTouchpadStatic(bool isTouched, Vector2 currentAxisValues, Vector2 previousAxisValues, int compareFidelity)
  406. {
  407. return (!isTouched || VRTK_SharedMethods.Vector2ShallowCompare(currentAxisValues, previousAxisValues, compareFidelity));
  408. }
  409. /// <summary>
  410. /// The GetButtonAxis method retrieves the current X/Y axis values for the given button type on the given controller reference.
  411. /// </summary>
  412. /// <param name="buttonType">The type of button to check for the axis on.</param>
  413. /// <param name="controllerReference">The reference to the controller to check the button axis on.</param>
  414. /// <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>
  415. public override Vector2 GetButtonAxis(ButtonTypes buttonType, VRTK_ControllerReference controllerReference)
  416. {
  417. if (!VRTK_ControllerReference.IsValid(controllerReference))
  418. {
  419. return Vector2.zero;
  420. }
  421. uint index = VRTK_ControllerReference.GetRealIndex(controllerReference);
  422. ControllerInput controllerInputDevice = GetControllerInputByIndex(index);
  423. TrackedObject trackedObjectDevice = GetTrackedObject(controllerReference.actual);
  424. switch (buttonType)
  425. {
  426. case ButtonTypes.Touchpad:
  427. if (controllerInputDevice != null)
  428. {
  429. Vector2 rawTouchpad = controllerInputDevice.GetTouchPos() - new Vector2(0.5f, 0.5f);
  430. return new Vector2(rawTouchpad.x, -rawTouchpad.y);
  431. }
  432. break;
  433. case ButtonTypes.Trigger:
  434. if (controllerInputDevice != null)
  435. {
  436. return new Vector2(controllerInputDevice.GetAxis(ControllerRawAxis.LeftTrigger), 0f);
  437. }
  438. break;
  439. case ButtonTypes.Grip:
  440. if (trackedObjectDevice != null)
  441. {
  442. return new Vector2((trackedObjectDevice.controllerInput.GetButton(DaydreamButton.Grip) ? 1f : 0f), 0f);
  443. }
  444. break;
  445. }
  446. return Vector2.zero;
  447. }
  448. /// <summary>
  449. /// The GetButtonSenseAxis method retrieves the current sense axis value for the given button type on the given controller reference.
  450. /// </summary>
  451. /// <param name="buttonType">The type of button to check for the sense axis on.</param>
  452. /// <param name="controllerReference">The reference to the controller to check the sense axis on.</param>
  453. /// <returns>The current sense axis value.</returns>
  454. public override float GetButtonSenseAxis(ButtonTypes buttonType, VRTK_ControllerReference controllerReference)
  455. {
  456. return 0f;
  457. }
  458. /// <summary>
  459. /// The GetButtonHairlineDelta method is used to get the difference between the current button press and the previous frame button press.
  460. /// </summary>
  461. /// <param name="buttonType">The type of button to get the hairline delta for.</param>
  462. /// <param name="controllerReference">The reference to the controller to get the hairline delta for.</param>
  463. /// <returns>The delta between the button presses.</returns>
  464. public override float GetButtonHairlineDelta(ButtonTypes buttonType, VRTK_ControllerReference controllerReference)
  465. {
  466. //TODO: This doesn't seem correct, surely this should be storing the previous button press value and getting the delta.
  467. return (VRTK_ControllerReference.IsValid(controllerReference) ? 0.1f : 0f);
  468. }
  469. /// <summary>
  470. /// 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.
  471. /// </summary>
  472. /// <param name="buttonType">The type of button to check for the state of.</param>
  473. /// <param name="pressType">The button state to check for.</param>
  474. /// <param name="controllerReference">The reference to the controller to check the button state on.</param>
  475. /// <returns>Returns true if the given button is in the state of the given press type on the given controller reference.</returns>
  476. public override bool GetControllerButtonState(ButtonTypes buttonType, ButtonPressTypes pressType, VRTK_ControllerReference controllerReference)
  477. {
  478. if (!VRTK_ControllerReference.IsValid(controllerReference))
  479. {
  480. return false;
  481. }
  482. uint index = VRTK_ControllerReference.GetRealIndex(controllerReference);
  483. switch (buttonType)
  484. {
  485. case ButtonTypes.Trigger:
  486. return IsButtonPressed(index, pressType, ControllerRawButton.LeftTrigger);
  487. case ButtonTypes.TriggerHairline:
  488. if (pressType == ButtonPressTypes.PressDown)
  489. {
  490. return (currentHairTriggerState[index] && !previousHairTriggerState[index]);
  491. }
  492. else if (pressType == ButtonPressTypes.PressUp)
  493. {
  494. return (!currentHairTriggerState[index] && previousHairTriggerState[index]);
  495. }
  496. break;
  497. case ButtonTypes.Grip:
  498. return IsButtonPressed(index, pressType, ControllerRawButton.LeftShoulder) || IsButtonPressed(index, pressType, ControllerRawButton.RightShoulder);
  499. case ButtonTypes.GripHairline:
  500. if (pressType == ButtonPressTypes.PressDown)
  501. {
  502. return (currentHairGripState[index] && !previousHairGripState[index]);
  503. }
  504. else if (pressType == ButtonPressTypes.PressUp)
  505. {
  506. return (!currentHairGripState[index] && previousHairGripState[index]);
  507. }
  508. break;
  509. case ButtonTypes.Touchpad:
  510. return IsButtonPressed(index, pressType, ControllerRawButton.LeftThumb);
  511. case ButtonTypes.ButtonOne:
  512. return IsButtonPressed(index, pressType, ControllerRawButton.Back);
  513. case ButtonTypes.ButtonTwo:
  514. return IsButtonPressed(index, pressType, ControllerRawButton.Start);
  515. }
  516. return false;
  517. }
  518. protected override void Awake()
  519. {
  520. base.Awake();
  521. SetTrackedControllerCaches(true);
  522. }
  523. protected virtual void OnTrackedDeviceRoleChanged<T>(T ignoredArgument)
  524. {
  525. SetTrackedControllerCaches(true);
  526. }
  527. protected virtual void SetTrackedControllerCaches(bool forceRefresh = false)
  528. {
  529. if (forceRefresh)
  530. {
  531. cachedLeftTrackedObject = null;
  532. cachedRightTrackedObject = null;
  533. }
  534. VRTK_SDKManager sdkManager = VRTK_SDKManager.instance;
  535. if (sdkManager != null)
  536. {
  537. if (cachedLeftTrackedObject == null && sdkManager.loadedSetup.actualLeftController)
  538. {
  539. cachedLeftTrackedObject = sdkManager.loadedSetup.actualLeftController.GetComponent<TrackedObject>();
  540. }
  541. if (cachedRightTrackedObject == null && sdkManager.loadedSetup.actualRightController)
  542. {
  543. cachedRightTrackedObject = sdkManager.loadedSetup.actualRightController.GetComponent<TrackedObject>();
  544. }
  545. }
  546. }
  547. protected virtual TrackedObject GetTrackedObject(GameObject controller)
  548. {
  549. SetTrackedControllerCaches();
  550. TrackedObject trackedObject = null;
  551. if (IsControllerLeftHand(controller))
  552. {
  553. trackedObject = cachedLeftTrackedObject;
  554. }
  555. else if (IsControllerRightHand(controller))
  556. {
  557. trackedObject = cachedRightTrackedObject;
  558. }
  559. return trackedObject;
  560. }
  561. protected virtual bool IsButtonPressed(uint index, ButtonPressTypes type, ControllerRawButton button)
  562. {
  563. ControllerInput device = GetControllerInputByIndex(index);
  564. if (device == null)
  565. {
  566. return false;
  567. }
  568. switch (type)
  569. {
  570. case ButtonPressTypes.Press:
  571. return device.GetButton(button);
  572. case ButtonPressTypes.PressDown:
  573. return device.GetButtonDown(button);
  574. case ButtonPressTypes.PressUp:
  575. return device.GetButtonUp(button);
  576. case ButtonPressTypes.Touch:
  577. return device.GetButton(button);
  578. case ButtonPressTypes.TouchDown:
  579. return device.GetButtonDown(button);
  580. case ButtonPressTypes.TouchUp:
  581. return device.GetButtonUp(button);
  582. }
  583. return false;
  584. }
  585. protected virtual void UpdateHairValues(uint index, float axisValue, float hairDelta, ref bool previousState, ref bool currentState, ref float hairLimit)
  586. {
  587. previousState = currentState;
  588. float value = axisValue;
  589. if (currentState)
  590. {
  591. if (value < (hairLimit - hairDelta) || value <= 0f)
  592. {
  593. currentState = false;
  594. }
  595. }
  596. else
  597. {
  598. if (value > (hairLimit + hairDelta) || value >= 1f)
  599. {
  600. currentState = true;
  601. }
  602. }
  603. hairLimit = (currentState ? Mathf.Max(hairLimit, value) : Mathf.Min(hairLimit, value));
  604. }
  605. protected virtual ControllerInput GetControllerInputByIndex(uint index)
  606. {
  607. ControllerInput result = null;
  608. switch (index)
  609. {
  610. case 0:
  611. result = ControllerInputManager.instance.GetControllerInput(ControllerType.LeftController);
  612. break;
  613. case 1:
  614. result = ControllerInputManager.instance.GetControllerInput(ControllerType.RightController);
  615. break;
  616. }
  617. return result;
  618. }
  619. #endif
  620. }
  621. }