Waypoint.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /*===============================================================================
  2. Copyright (C) 2022 Immersal - Part of Hexagon. All Rights Reserved.
  3. This file is part of the Immersal SDK.
  4. The Immersal SDK cannot be copied, distributed, or made available to
  5. third-parties for commercial purposes without written permission of Immersal Ltd.
  6. Contact sdk@immersal.com for licensing requests.
  7. ===============================================================================*/
  8. using System.Collections;
  9. using System.Collections.Generic;
  10. using UnityEngine;
  11. using UnityEngine.EventSystems;
  12. using UnityEngine.UI;
  13. namespace Immersal.Samples.Navigation
  14. {
  15. public class Waypoint : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
  16. {
  17. public List<Waypoint> neighbours = new List<Waypoint>();
  18. public Vector3 position
  19. {
  20. get
  21. {
  22. return m_collider.bounds.center;
  23. }
  24. set
  25. {
  26. }
  27. }
  28. [SerializeField]
  29. private float m_ClickHoldTime = 1f;
  30. private float m_timeHeld = 0f;
  31. private Collider m_collider = null;
  32. private bool isPressed = false;
  33. private bool isEditing = false;
  34. private Camera m_mainCamera = null;
  35. private float m_DragPlaneDistance = 0f;
  36. private MeshFilter m_MeshFilter = null;
  37. private MeshRenderer m_MeshRenderer = null;
  38. private Mesh m_Mesh = null;
  39. void Start()
  40. {
  41. m_mainCamera = Camera.main;
  42. InitializeNode();
  43. NavigationGraphManager.Instance.AddWaypoint(this);
  44. }
  45. private void InitializeNode()
  46. {
  47. m_collider = GetComponent<Collider>();
  48. if (m_collider == null)
  49. m_collider = gameObject.AddComponent<SphereCollider>();
  50. if (m_Mesh == null)
  51. m_Mesh = new Mesh();
  52. m_MeshFilter = GetComponent<MeshFilter>();
  53. m_MeshRenderer = GetComponent<MeshRenderer>();
  54. if (m_MeshFilter == null)
  55. m_MeshFilter = gameObject.AddComponent<MeshFilter>();
  56. if (m_MeshRenderer == null)
  57. m_MeshRenderer = gameObject.AddComponent<MeshRenderer>();
  58. m_MeshFilter.mesh = m_Mesh;
  59. }
  60. void Update()
  61. {
  62. if (isPressed)
  63. {
  64. Vector3 projection = m_mainCamera.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, m_DragPlaneDistance));
  65. DrawPreviewConnection(position, projection, 0.1f, m_Mesh);
  66. RaycastHit hit;
  67. Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
  68. if (Physics.Raycast(ray, out hit))
  69. {
  70. if (hit.collider != null)
  71. {
  72. Waypoint wp = hit.collider.GetComponent<Waypoint>();
  73. if (wp == this)
  74. {
  75. m_timeHeld += Time.deltaTime;
  76. }
  77. else
  78. {
  79. m_timeHeld = 0f;
  80. }
  81. }
  82. }
  83. if (m_timeHeld >= m_ClickHoldTime && !isEditing)
  84. {
  85. isEditing = true;
  86. }
  87. if (isEditing)
  88. {
  89. transform.position = projection;
  90. }
  91. }
  92. }
  93. private void OnDestroy()
  94. {
  95. NavigationGraphManager.Instance.RemoveWaypoint(this);
  96. }
  97. private void DrawPreviewConnection(Vector3 startPosition, Vector3 endPosition, float lineWidth, Mesh mesh)
  98. {
  99. Vector3 camPos = m_mainCamera.transform.position;
  100. float length = (endPosition - startPosition).magnitude;
  101. List<Vector3> points = new List<Vector3>();
  102. points.Add(startPosition);
  103. points.Add(endPosition);
  104. Vector3[] x = new Vector3[2];
  105. Vector3[] z = new Vector3[2];
  106. Vector3[] y = new Vector3[2];
  107. Quaternion[] q = new Quaternion[2];
  108. Matrix4x4[] m = new Matrix4x4[2];
  109. z[0] = (endPosition - startPosition).normalized;
  110. z[1] = (startPosition - endPosition).normalized;
  111. y[0] = (camPos - startPosition).normalized;
  112. y[1] = (camPos - endPosition).normalized;
  113. x[0] = Vector3.Cross(y[0], z[0]);
  114. x[1] = Vector3.Cross(y[1], -z[1]);
  115. //Debug.DrawRay(startPosition, x[0] * 0.4f, Color.red);
  116. //Debug.DrawRay(endPosition, x[0] * 0.4f, Color.red);
  117. //Debug.DrawRay(startPosition, y[0] * 0.4f, Color.green);
  118. //Debug.DrawRay(endPosition, y[0] * 0.4f, Color.green);
  119. //Debug.DrawRay(startPosition, z[0] * 0.4f, Color.blue);
  120. //Debug.DrawRay(endPosition, z[0] * 0.4f, Color.blue);
  121. Vector3[] vtx = new Vector3[4];
  122. int[] idx = new int[6];
  123. Vector2[] uv = new Vector2[4];
  124. vtx[0] = transform.worldToLocalMatrix.MultiplyPoint(new Vector3(startPosition.x, startPosition.y, startPosition.z) - (x[0] * lineWidth * 0.5f));
  125. vtx[1] = transform.worldToLocalMatrix.MultiplyPoint(new Vector3(endPosition.x, endPosition.y, endPosition.z) - (x[1] * lineWidth * 0.5f));
  126. vtx[2] = transform.worldToLocalMatrix.MultiplyPoint(new Vector3(endPosition.x, endPosition.y, endPosition.z) + (x[1] * lineWidth * 0.5f));
  127. vtx[3] = transform.worldToLocalMatrix.MultiplyPoint(new Vector3(startPosition.x, startPosition.y, startPosition.z) + (x[0] * lineWidth * 0.5f));
  128. idx[0] = 0;
  129. idx[1] = 1;
  130. idx[2] = 3;
  131. idx[3] = 1;
  132. idx[4] = 2;
  133. idx[5] = 3;
  134. uv[0] = new Vector2(0f, 0f);
  135. uv[1] = new Vector2(1f, 0f);
  136. uv[2] = new Vector2(1f, 1f);
  137. uv[3] = new Vector2(0f, 1f);
  138. mesh.Clear();
  139. mesh.vertices = vtx;
  140. mesh.triangles = idx;
  141. mesh.uv = uv;
  142. }
  143. public void OnPointerDown(PointerEventData eventData)
  144. {
  145. if (Immersal.Samples.Navigation.NavigationManager.Instance.inEditMode)
  146. {
  147. Debug.Log("pointer down");
  148. Debug.Log(m_timeHeld);
  149. isPressed = true;
  150. m_DragPlaneDistance = Vector3.Dot(transform.position - m_mainCamera.transform.position, m_mainCamera.transform.forward) / m_mainCamera.transform.forward.sqrMagnitude;
  151. }
  152. }
  153. public void OnPointerUp(PointerEventData eventData)
  154. {
  155. isPressed = false;
  156. isEditing = false;
  157. m_timeHeld = 0f;
  158. m_Mesh.Clear();
  159. if (Immersal.Samples.Navigation.NavigationManager.Instance.inEditMode)
  160. {
  161. RaycastHit hit;
  162. Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
  163. if (Physics.Raycast(ray, out hit))
  164. {
  165. if (hit.collider != null)
  166. {
  167. Waypoint wp = hit.collider.GetComponent<Waypoint>();
  168. if (wp != null && wp != this)
  169. {
  170. if (!neighbours.Contains(wp))
  171. {
  172. neighbours.Add(wp);
  173. }
  174. if (!wp.neighbours.Contains(this))
  175. {
  176. wp.neighbours.Add(this);
  177. }
  178. }
  179. }
  180. }
  181. }
  182. }
  183. }
  184. }