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.

343 lines
14 KiB

  1. namespace VRTK
  2. {
  3. using UnityEngine;
  4. using UnityEngine.EventSystems;
  5. using UnityEngine.UI;
  6. using System.Collections.Generic;
  7. public class VRTK_VRInputModule : PointerInputModule
  8. {
  9. public List<VRTK_UIPointer> pointers = new List<VRTK_UIPointer>();
  10. public virtual void Initialise()
  11. {
  12. pointers.Clear();
  13. }
  14. //Needed to allow other regular (non-VR) InputModules in combination with VRTK_EventSystem
  15. public override bool IsModuleSupported()
  16. {
  17. return false;
  18. }
  19. public override void Process()
  20. {
  21. for (int i = 0; i < pointers.Count; i++)
  22. {
  23. VRTK_UIPointer pointer = pointers[i];
  24. if (pointer.gameObject.activeInHierarchy && pointer.enabled)
  25. {
  26. List<RaycastResult> results = new List<RaycastResult>();
  27. if (pointer.PointerActive())
  28. {
  29. results = CheckRaycasts(pointer);
  30. }
  31. //Process events
  32. Hover(pointer, results);
  33. Click(pointer, results);
  34. Drag(pointer, results);
  35. Scroll(pointer, results);
  36. }
  37. }
  38. }
  39. protected virtual List<RaycastResult> CheckRaycasts(VRTK_UIPointer pointer)
  40. {
  41. RaycastResult raycastResult = new RaycastResult();
  42. raycastResult.worldPosition = pointer.GetOriginPosition();
  43. raycastResult.worldNormal = pointer.GetOriginForward();
  44. pointer.pointerEventData.pointerCurrentRaycast = raycastResult;
  45. List<RaycastResult> raycasts = new List<RaycastResult>();
  46. eventSystem.RaycastAll(pointer.pointerEventData, raycasts);
  47. return raycasts;
  48. }
  49. protected virtual bool CheckTransformTree(Transform target, Transform source)
  50. {
  51. if (target == null)
  52. {
  53. return false;
  54. }
  55. if (target == source)
  56. {
  57. return true;
  58. }
  59. return CheckTransformTree(target.transform.parent, source);
  60. }
  61. protected virtual bool NoValidCollision(VRTK_UIPointer pointer, List<RaycastResult> results)
  62. {
  63. return (results.Count == 0 || !CheckTransformTree(results[0].gameObject.transform, pointer.pointerEventData.pointerEnter.transform));
  64. }
  65. protected virtual bool IsHovering(VRTK_UIPointer pointer)
  66. {
  67. for (int i = 0; i < pointer.pointerEventData.hovered.Count; i++)
  68. {
  69. GameObject hoveredObject = pointer.pointerEventData.hovered[i];
  70. if (pointer.pointerEventData.pointerEnter != null && hoveredObject != null && CheckTransformTree(hoveredObject.transform, pointer.pointerEventData.pointerEnter.transform))
  71. {
  72. return true;
  73. }
  74. }
  75. return false;
  76. }
  77. protected virtual bool ValidElement(GameObject obj)
  78. {
  79. VRTK_UICanvas canvasCheck = obj.GetComponentInParent<VRTK_UICanvas>();
  80. return (canvasCheck != null && canvasCheck.enabled ? true : false);
  81. }
  82. protected virtual void CheckPointerHoverClick(VRTK_UIPointer pointer, List<RaycastResult> results)
  83. {
  84. if (pointer.hoverDurationTimer > 0f)
  85. {
  86. pointer.hoverDurationTimer -= Time.deltaTime;
  87. }
  88. if (pointer.canClickOnHover && pointer.hoverDurationTimer <= 0f)
  89. {
  90. pointer.canClickOnHover = false;
  91. ClickOnDown(pointer, results, true);
  92. }
  93. }
  94. protected virtual void Hover(VRTK_UIPointer pointer, List<RaycastResult> results)
  95. {
  96. if (pointer.pointerEventData.pointerEnter != null)
  97. {
  98. CheckPointerHoverClick(pointer, results);
  99. if (!ValidElement(pointer.pointerEventData.pointerEnter))
  100. {
  101. pointer.pointerEventData.pointerEnter = null;
  102. return;
  103. }
  104. if (NoValidCollision(pointer, results))
  105. {
  106. ExecuteEvents.ExecuteHierarchy(pointer.pointerEventData.pointerEnter, pointer.pointerEventData, ExecuteEvents.pointerExitHandler);
  107. pointer.pointerEventData.hovered.Remove(pointer.pointerEventData.pointerEnter);
  108. pointer.pointerEventData.pointerEnter = null;
  109. }
  110. }
  111. else
  112. {
  113. for (int i = 0; i < results.Count; i++)
  114. {
  115. RaycastResult result = results[i];
  116. if (!ValidElement(result.gameObject))
  117. {
  118. continue;
  119. }
  120. GameObject target = ExecuteEvents.ExecuteHierarchy(result.gameObject, pointer.pointerEventData, ExecuteEvents.pointerEnterHandler);
  121. target = (target == null ? result.gameObject : target);
  122. if (target != null)
  123. {
  124. Selectable selectable = target.GetComponent<Selectable>();
  125. if (selectable != null)
  126. {
  127. Navigation noNavigation = new Navigation();
  128. noNavigation.mode = Navigation.Mode.None;
  129. selectable.navigation = noNavigation;
  130. }
  131. if (pointer.hoveringElement != null && pointer.hoveringElement != target)
  132. {
  133. pointer.OnUIPointerElementExit(pointer.SetUIPointerEvent(result, null, pointer.hoveringElement));
  134. }
  135. pointer.OnUIPointerElementEnter(pointer.SetUIPointerEvent(result, target, pointer.hoveringElement));
  136. pointer.hoveringElement = target;
  137. pointer.pointerEventData.pointerCurrentRaycast = result;
  138. pointer.pointerEventData.pointerEnter = target;
  139. pointer.pointerEventData.hovered.Add(pointer.pointerEventData.pointerEnter);
  140. break;
  141. }
  142. if (result.gameObject != pointer.hoveringElement)
  143. {
  144. pointer.OnUIPointerElementEnter(pointer.SetUIPointerEvent(result, result.gameObject, pointer.hoveringElement));
  145. }
  146. pointer.hoveringElement = result.gameObject;
  147. }
  148. if (pointer.hoveringElement && results.Count == 0)
  149. {
  150. pointer.OnUIPointerElementExit(pointer.SetUIPointerEvent(new RaycastResult(), null, pointer.hoveringElement));
  151. pointer.hoveringElement = null;
  152. }
  153. }
  154. }
  155. protected virtual void Click(VRTK_UIPointer pointer, List<RaycastResult> results)
  156. {
  157. switch (pointer.clickMethod)
  158. {
  159. case VRTK_UIPointer.ClickMethods.ClickOnButtonUp:
  160. ClickOnUp(pointer, results);
  161. break;
  162. case VRTK_UIPointer.ClickMethods.ClickOnButtonDown:
  163. ClickOnDown(pointer, results);
  164. break;
  165. }
  166. }
  167. protected virtual void ClickOnUp(VRTK_UIPointer pointer, List<RaycastResult> results)
  168. {
  169. pointer.pointerEventData.eligibleForClick = pointer.ValidClick(false);
  170. if (!AttemptClick(pointer))
  171. {
  172. IsEligibleClick(pointer, results);
  173. }
  174. }
  175. protected virtual void ClickOnDown(VRTK_UIPointer pointer, List<RaycastResult> results, bool forceClick = false)
  176. {
  177. pointer.pointerEventData.eligibleForClick = (forceClick ? true : pointer.ValidClick(true));
  178. if (IsEligibleClick(pointer, results))
  179. {
  180. pointer.pointerEventData.eligibleForClick = false;
  181. AttemptClick(pointer);
  182. }
  183. }
  184. protected virtual bool IsEligibleClick(VRTK_UIPointer pointer, List<RaycastResult> results)
  185. {
  186. if (pointer.pointerEventData.eligibleForClick)
  187. {
  188. for (int i = 0; i < results.Count; i++)
  189. {
  190. RaycastResult result = results[i];
  191. if (!ValidElement(result.gameObject))
  192. {
  193. continue;
  194. }
  195. GameObject target = ExecuteEvents.ExecuteHierarchy(result.gameObject, pointer.pointerEventData, ExecuteEvents.pointerDownHandler);
  196. if (target != null)
  197. {
  198. pointer.pointerEventData.pressPosition = pointer.pointerEventData.position;
  199. pointer.pointerEventData.pointerPressRaycast = result;
  200. pointer.pointerEventData.pointerPress = target;
  201. return true;
  202. }
  203. }
  204. }
  205. return false;
  206. }
  207. protected virtual bool AttemptClick(VRTK_UIPointer pointer)
  208. {
  209. if (pointer.pointerEventData.pointerPress)
  210. {
  211. if (!ValidElement(pointer.pointerEventData.pointerPress))
  212. {
  213. pointer.pointerEventData.pointerPress = null;
  214. return true;
  215. }
  216. if (pointer.pointerEventData.eligibleForClick)
  217. {
  218. if (!IsHovering(pointer))
  219. {
  220. ExecuteEvents.ExecuteHierarchy(pointer.pointerEventData.pointerPress, pointer.pointerEventData, ExecuteEvents.pointerUpHandler);
  221. pointer.pointerEventData.pointerPress = null;
  222. }
  223. }
  224. else
  225. {
  226. pointer.OnUIPointerElementClick(pointer.SetUIPointerEvent(pointer.pointerEventData.pointerPressRaycast, pointer.pointerEventData.pointerPress));
  227. ExecuteEvents.ExecuteHierarchy(pointer.pointerEventData.pointerPress, pointer.pointerEventData, ExecuteEvents.pointerClickHandler);
  228. ExecuteEvents.ExecuteHierarchy(pointer.pointerEventData.pointerPress, pointer.pointerEventData, ExecuteEvents.pointerUpHandler);
  229. pointer.pointerEventData.pointerPress = null;
  230. }
  231. return true;
  232. }
  233. return false;
  234. }
  235. protected virtual void Drag(VRTK_UIPointer pointer, List<RaycastResult> results)
  236. {
  237. pointer.pointerEventData.dragging = pointer.IsSelectionButtonPressed() && pointer.pointerEventData.delta != Vector2.zero;
  238. if (pointer.pointerEventData.pointerDrag)
  239. {
  240. if (!ValidElement(pointer.pointerEventData.pointerDrag))
  241. {
  242. pointer.pointerEventData.pointerDrag = null;
  243. return;
  244. }
  245. if (pointer.pointerEventData.dragging)
  246. {
  247. if (IsHovering(pointer))
  248. {
  249. ExecuteEvents.ExecuteHierarchy(pointer.pointerEventData.pointerDrag, pointer.pointerEventData, ExecuteEvents.dragHandler);
  250. }
  251. }
  252. else
  253. {
  254. ExecuteEvents.ExecuteHierarchy(pointer.pointerEventData.pointerDrag, pointer.pointerEventData, ExecuteEvents.dragHandler);
  255. ExecuteEvents.ExecuteHierarchy(pointer.pointerEventData.pointerDrag, pointer.pointerEventData, ExecuteEvents.endDragHandler);
  256. for (int i = 0; i < results.Count; i++)
  257. {
  258. ExecuteEvents.ExecuteHierarchy(results[i].gameObject, pointer.pointerEventData, ExecuteEvents.dropHandler);
  259. }
  260. pointer.pointerEventData.pointerDrag = null;
  261. }
  262. }
  263. else if (pointer.pointerEventData.dragging)
  264. {
  265. for (int i = 0; i < results.Count; i++)
  266. {
  267. RaycastResult result = results[i];
  268. if (!ValidElement(result.gameObject))
  269. {
  270. continue;
  271. }
  272. ExecuteEvents.ExecuteHierarchy(result.gameObject, pointer.pointerEventData, ExecuteEvents.initializePotentialDrag);
  273. ExecuteEvents.ExecuteHierarchy(result.gameObject, pointer.pointerEventData, ExecuteEvents.beginDragHandler);
  274. GameObject target = ExecuteEvents.ExecuteHierarchy(result.gameObject, pointer.pointerEventData, ExecuteEvents.dragHandler);
  275. if (target != null)
  276. {
  277. pointer.pointerEventData.pointerDrag = target;
  278. break;
  279. }
  280. }
  281. }
  282. }
  283. protected virtual void Scroll(VRTK_UIPointer pointer, List<RaycastResult> results)
  284. {
  285. pointer.pointerEventData.scrollDelta = (pointer.controllerEvents != null ? pointer.controllerEvents.GetTouchpadAxis() : Vector2.zero);
  286. bool scrollWheelVisible = false;
  287. for (int i = 0; i < results.Count; i++)
  288. {
  289. if (pointer.pointerEventData.scrollDelta != Vector2.zero)
  290. {
  291. GameObject target = ExecuteEvents.ExecuteHierarchy(results[i].gameObject, pointer.pointerEventData, ExecuteEvents.scrollHandler);
  292. if (target != null)
  293. {
  294. scrollWheelVisible = true;
  295. }
  296. }
  297. }
  298. if (pointer.controllerRenderModel != null)
  299. {
  300. VRTK_SDK_Bridge.SetControllerRenderModelWheel(pointer.controllerRenderModel, scrollWheelVisible);
  301. }
  302. }
  303. }
  304. }