GizmosEx.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. #if UNITY_EDITOR
  2. using UnityEngine;
  3. using System.Collections.Generic;
  4. namespace O3DWB
  5. {
  6. public static class GizmosEx
  7. {
  8. #region Private Static Variables
  9. private static Mesh _xyRectangleMesh;
  10. private static Mesh _xzRectangleMesh;
  11. private static Mesh _xyCircleMesh;
  12. private static int _numberOfCircleMeshSlices = 80;
  13. private static float _2DPointOffsetFromCamNearPlane = 0.01f;
  14. #endregion
  15. public static Mesh XZRectangleMesh
  16. {
  17. get
  18. {
  19. if (_xzRectangleMesh == null) _xzRectangleMesh = Octave3DWorldBuilder.ActiveInstance.ToolResources.MeshResources.CreateXZRectangleMesh(1.0f, 1.0f, Color.white);
  20. return _xzRectangleMesh;
  21. }
  22. }
  23. #region Public Static Functions
  24. public static void Render2DFilledSquare(Square2D square, Color color)
  25. {
  26. Render2DFilledRectangle(square.ToRectangle(), color);
  27. }
  28. public static void Render2DFilledRectangle(Rect rectangle, Color color)
  29. {
  30. Camera camera = SceneViewCamera.Camera;
  31. Transform cameraTransform = camera.transform;
  32. List<Vector3> rectWorldPoints = rectangle.GetWorldCornerPointsInFrontOfCamera(camera, _2DPointOffsetFromCamNearPlane);
  33. float width = (rectWorldPoints[0] - rectWorldPoints[1]).magnitude;
  34. float height = (rectWorldPoints[1] - rectWorldPoints[2]).magnitude;
  35. Vector3 rectangleWorldPosition = rectangle.GetWorldCenterPointInFrontOfCamera(camera, _2DPointOffsetFromCamNearPlane);
  36. Matrix4x4 transformMatrix = Matrix4x4.TRS(rectangleWorldPosition, cameraTransform.rotation, new Vector3(width, height, 1.0f));
  37. RenderMesh(GetRectangleMesh(), transformMatrix, color);
  38. }
  39. public static void Render2DSquareBorderLines(Square2D square, Color color)
  40. {
  41. Render2DRectangleBorderLines(square.ToRectangle(), color);
  42. }
  43. public static void Render2DRectangleBorderLines(Rect rectangle, Color color)
  44. {
  45. Camera camera = SceneViewCamera.Camera;
  46. List<Vector3> rectWorldPoints = rectangle.GetWorldCornerPointsInFrontOfCamera(camera, _2DPointOffsetFromCamNearPlane);
  47. RenderLinesBetweenPoints(rectWorldPoints, color);
  48. }
  49. public static void Render2DFilledCircle(Circle2D circle, Color color)
  50. {
  51. Render2DFilledEllipse(new Ellipse2D(circle), color);
  52. }
  53. public static void Render2DFilledEllipse(Ellipse2D ellipse, Color color)
  54. {
  55. Camera camera = SceneViewCamera.Camera;
  56. Transform cameraTransform = camera.transform;
  57. List<Vector3> ellipseWorldPoints = ellipse.GetWorldExtentPointsInFrontOfCamera(camera, _2DPointOffsetFromCamNearPlane);
  58. float radiusX = (ellipseWorldPoints[1] - ellipseWorldPoints[3]).magnitude * 0.5f;
  59. float radiusY = (ellipseWorldPoints[0] - ellipseWorldPoints[2]).magnitude * 0.5f;
  60. Vector3 ellipseWorldPosition = ellipse.GetWorldCenterPointInFrontOfCamera(camera, _2DPointOffsetFromCamNearPlane);
  61. Matrix4x4 transformMatrix = Matrix4x4.TRS(ellipseWorldPosition, cameraTransform.rotation, new Vector3(radiusX, radiusY, 1.0f));
  62. RenderMesh(GetCircleMesh(), transformMatrix, color);
  63. }
  64. public static void Render2DCircleBorderLines(Circle2D circle, Color color)
  65. {
  66. Ellipse2D ellipse = new Ellipse2D(circle);
  67. Render2DEllipseBorderLines(ellipse, color);
  68. }
  69. public static void Render2DEllipseBorderLines(Ellipse2D ellipse, Color color)
  70. {
  71. Camera camera = SceneViewCamera.Camera;
  72. List<Vector3> worldBorderPoints = ellipse.GetWorldBorderLinesInFrontOfCamera(camera, _2DPointOffsetFromCamNearPlane, _numberOfCircleMeshSlices);
  73. RenderLinesBetweenPoints(worldBorderPoints, color);
  74. }
  75. public static void RenderXZOrientedQuad(XZOrientedQuad3D orientedQuad, Color color)
  76. {
  77. GizmosMatrix.Push(orientedQuad.TransformMatrix.ToMatrix4x4x);
  78. GizmosColor.Push(color);
  79. Gizmos.DrawCube(Vector3.zero, new Vector3(orientedQuad.ModelSpaceXZSize.x, 0.0f, orientedQuad.ModelSpaceXZSize.y));
  80. GizmosColor.Pop();
  81. GizmosMatrix.Pop();
  82. }
  83. public static void RenderXZOrientedQuad(XZOrientedQuad3D orientedQuad, Color color, float offsetAlongNormal)
  84. {
  85. Matrix4x4 translationMatrix = Matrix4x4.TRS(orientedQuad.Plane.normal * offsetAlongNormal, Quaternion.identity, Vector3.one);
  86. GizmosMatrix.Push(translationMatrix * orientedQuad.TransformMatrix.ToMatrix4x4x);
  87. GizmosColor.Push(color);
  88. Gizmos.DrawCube(Vector3.zero, new Vector3(orientedQuad.ModelSpaceXZSize.x, 0.0f, orientedQuad.ModelSpaceXZSize.y));
  89. GizmosColor.Pop();
  90. GizmosMatrix.Pop();
  91. }
  92. public static void RenderXZOrientedQuadBorderLines(XZOrientedQuad3D orientedQuad, Color color)
  93. {
  94. RenderLinesBetweenPoints(orientedQuad.GetCornerPoints(), color);
  95. }
  96. public static void RenderXZOrientedQuadBorderLines(XZOrientedQuad3D orientedQuad, Color color, float offsetAlongNormal)
  97. {
  98. List<Vector3> cornerPoints = orientedQuad.GetCornerPoints();
  99. cornerPoints = Vector3Extensions.ApplyOffsetToPoints(cornerPoints, orientedQuad.Plane.normal * offsetAlongNormal);
  100. RenderLinesBetweenPoints(cornerPoints, color);
  101. }
  102. public static void RenderOrientedBox(OrientedBox orientedBox, Color color)
  103. {
  104. Matrix4x4 transformMatrix = Matrix4x4.TRS(orientedBox.Center, orientedBox.Rotation, orientedBox.ScaledSize);
  105. GizmosMatrix.Push(transformMatrix);
  106. GizmosColor.Push(color);
  107. Gizmos.DrawCube(Vector3.zero, Vector3.one);
  108. GizmosColor.Pop();
  109. GizmosMatrix.Pop();
  110. }
  111. public static void RenderBoxEdges(Box box, Color color)
  112. {
  113. GizmosColor.Push(color);
  114. Gizmos.DrawWireCube(box.Center, box.Size);
  115. GizmosColor.Pop();
  116. }
  117. public static void RenderOrientedBoxEdges(OrientedBox orientedBox, Color color)
  118. {
  119. GizmosColor.Push(color);
  120. GizmosMatrix.Push(Matrix4x4.TRS(orientedBox.Center, orientedBox.Rotation, orientedBox.ScaledSize));
  121. Gizmos.DrawWireCube(Vector3.zero, Vector3.one);
  122. GizmosMatrix.Pop();
  123. GizmosColor.Pop();
  124. }
  125. public static void RenderOrientedBoxCornerEdges(OrientedBox orientedBox, float cornerEdgeLengthPercentage, Color color)
  126. {
  127. cornerEdgeLengthPercentage = Mathf.Clamp(cornerEdgeLengthPercentage, 0.0f, 1.0f);
  128. List<Vector3> boxCornerPoints = orientedBox.GetCenterAndCornerPoints();
  129. GizmosColor.Push(color);
  130. // Render the corner edges along the top edge of the box's front face
  131. Segment3D segment = new Segment3D(boxCornerPoints[(int)BoxPoint.FrontTopLeft], boxCornerPoints[(int)BoxPoint.FrontTopRight]);
  132. float edgeLength = segment.HalfLength * cornerEdgeLengthPercentage;
  133. if (edgeLength > 0.0f)
  134. {
  135. Gizmos.DrawLine(segment.StartPoint, segment.StartPoint + segment.NormalizedDirection * edgeLength);
  136. Gizmos.DrawLine(segment.EndPoint, segment.EndPoint - segment.NormalizedDirection * edgeLength);
  137. }
  138. // Render the corner edges along the bottom edge of the box's front face
  139. segment = new Segment3D(boxCornerPoints[(int)BoxPoint.FrontBottomLeft], boxCornerPoints[(int)BoxPoint.FrontBottomRight]);
  140. edgeLength = segment.HalfLength * cornerEdgeLengthPercentage;
  141. if (edgeLength > 0.0f)
  142. {
  143. Gizmos.DrawLine(segment.StartPoint, segment.StartPoint + segment.NormalizedDirection * edgeLength);
  144. Gizmos.DrawLine(segment.EndPoint, segment.EndPoint - segment.NormalizedDirection * edgeLength);
  145. }
  146. // Render the corner edges along the left edge of the box's front face
  147. segment = new Segment3D(boxCornerPoints[(int)BoxPoint.FrontTopLeft], boxCornerPoints[(int)BoxPoint.FrontBottomLeft]);
  148. edgeLength = segment.HalfLength * cornerEdgeLengthPercentage;
  149. if (edgeLength > 0.0f)
  150. {
  151. Gizmos.DrawLine(segment.StartPoint, segment.StartPoint + segment.NormalizedDirection * edgeLength);
  152. Gizmos.DrawLine(segment.EndPoint, segment.EndPoint - segment.NormalizedDirection * edgeLength);
  153. }
  154. // Render the corner edges along the right edge of the box's front face
  155. segment = new Segment3D(boxCornerPoints[(int)BoxPoint.FrontTopRight], boxCornerPoints[(int)BoxPoint.FrontBottomRight]);
  156. edgeLength = segment.HalfLength * cornerEdgeLengthPercentage;
  157. if (edgeLength > 0.0f)
  158. {
  159. Gizmos.DrawLine(segment.StartPoint, segment.StartPoint + segment.NormalizedDirection * edgeLength);
  160. Gizmos.DrawLine(segment.EndPoint, segment.EndPoint - segment.NormalizedDirection * edgeLength);
  161. }
  162. // Render the corner edges along the top edge of the box's back face
  163. segment = new Segment3D(boxCornerPoints[(int)BoxPoint.BackTopLeft], boxCornerPoints[(int)BoxPoint.BackTopRight]);
  164. edgeLength = segment.HalfLength * cornerEdgeLengthPercentage;
  165. if (edgeLength > 0.0f)
  166. {
  167. Gizmos.DrawLine(segment.StartPoint, segment.StartPoint + segment.NormalizedDirection * edgeLength);
  168. Gizmos.DrawLine(segment.EndPoint, segment.EndPoint - segment.NormalizedDirection * edgeLength);
  169. }
  170. // Render the corner edges along the bottom edge of the box's back face
  171. segment = new Segment3D(boxCornerPoints[(int)BoxPoint.BackBottomLeft], boxCornerPoints[(int)BoxPoint.BackBottomRight]);
  172. edgeLength = segment.HalfLength * cornerEdgeLengthPercentage;
  173. if (edgeLength > 0.0f)
  174. {
  175. Gizmos.DrawLine(segment.StartPoint, segment.StartPoint + segment.NormalizedDirection * edgeLength);
  176. Gizmos.DrawLine(segment.EndPoint, segment.EndPoint - segment.NormalizedDirection * edgeLength);
  177. }
  178. // Render the corner edges along the left edge of the box's back face
  179. segment = new Segment3D(boxCornerPoints[(int)BoxPoint.BackTopLeft], boxCornerPoints[(int)BoxPoint.BackBottomLeft]);
  180. edgeLength = segment.HalfLength * cornerEdgeLengthPercentage;
  181. if (edgeLength > 0.0f)
  182. {
  183. Gizmos.DrawLine(segment.StartPoint, segment.StartPoint + segment.NormalizedDirection * edgeLength);
  184. Gizmos.DrawLine(segment.EndPoint, segment.EndPoint - segment.NormalizedDirection * edgeLength);
  185. }
  186. // Render the corner edges along the right edge of the box's back face
  187. segment = new Segment3D(boxCornerPoints[(int)BoxPoint.BackTopRight], boxCornerPoints[(int)BoxPoint.BackBottomRight]);
  188. edgeLength = segment.HalfLength * cornerEdgeLengthPercentage;
  189. if (edgeLength > 0.0f)
  190. {
  191. Gizmos.DrawLine(segment.StartPoint, segment.StartPoint + segment.NormalizedDirection * edgeLength);
  192. Gizmos.DrawLine(segment.EndPoint, segment.EndPoint - segment.NormalizedDirection * edgeLength);
  193. }
  194. // Render the corner edges along the left edge of the box's top face
  195. segment = new Segment3D(boxCornerPoints[(int)BoxPoint.FrontTopLeft], boxCornerPoints[(int)BoxPoint.BackTopRight]);
  196. edgeLength = segment.HalfLength * cornerEdgeLengthPercentage;
  197. if (edgeLength > 0.0f)
  198. {
  199. Gizmos.DrawLine(segment.StartPoint, segment.StartPoint + segment.NormalizedDirection * edgeLength);
  200. Gizmos.DrawLine(segment.EndPoint, segment.EndPoint - segment.NormalizedDirection * edgeLength);
  201. }
  202. // Render the corner edges along the right edge of the box's top face
  203. segment = new Segment3D(boxCornerPoints[(int)BoxPoint.FrontTopRight], boxCornerPoints[(int)BoxPoint.BackTopLeft]);
  204. edgeLength = segment.HalfLength * cornerEdgeLengthPercentage;
  205. if (edgeLength > 0.0f)
  206. {
  207. Gizmos.DrawLine(segment.StartPoint, segment.StartPoint + segment.NormalizedDirection * edgeLength);
  208. Gizmos.DrawLine(segment.EndPoint, segment.EndPoint - segment.NormalizedDirection * edgeLength);
  209. }
  210. // Render the corner edges along the left edge of the box's bottom face
  211. segment = new Segment3D(boxCornerPoints[(int)BoxPoint.FrontBottomLeft], boxCornerPoints[(int)BoxPoint.BackBottomRight]);
  212. edgeLength = segment.HalfLength * cornerEdgeLengthPercentage;
  213. if (edgeLength > 0.0f)
  214. {
  215. Gizmos.DrawLine(segment.StartPoint, segment.StartPoint + segment.NormalizedDirection * edgeLength);
  216. Gizmos.DrawLine(segment.EndPoint, segment.EndPoint - segment.NormalizedDirection * edgeLength);
  217. }
  218. // Render the corner edges along the right edge of the box's bottom face
  219. segment = new Segment3D(boxCornerPoints[(int)BoxPoint.FrontBottomRight], boxCornerPoints[(int)BoxPoint.BackBottomLeft]);
  220. edgeLength = segment.HalfLength * cornerEdgeLengthPercentage;
  221. if (edgeLength > 0.0f)
  222. {
  223. Gizmos.DrawLine(segment.StartPoint, segment.StartPoint + segment.NormalizedDirection * edgeLength);
  224. Gizmos.DrawLine(segment.EndPoint, segment.EndPoint - segment.NormalizedDirection * edgeLength);
  225. }
  226. GizmosColor.Pop();
  227. }
  228. public static void RenderMesh(Mesh mesh, Matrix4x4 transformMatrix, Color color)
  229. {
  230. GizmosMatrix.Push(transformMatrix);
  231. GizmosColor.Push(color);
  232. Gizmos.DrawMesh(mesh);
  233. GizmosColor.Pop();
  234. GizmosMatrix.Pop();
  235. }
  236. public static void RenderLinesBetweenPoints(List<Vector3> points, Color color)
  237. {
  238. GizmosMatrix.Push(Matrix4x4.identity);
  239. GizmosColor.Push(color);
  240. int numberOfPoints = points.Count;
  241. for (int pointIndex = 0; pointIndex < numberOfPoints; ++pointIndex)
  242. {
  243. Gizmos.DrawLine(points[pointIndex], points[(pointIndex + 1) % numberOfPoints]);
  244. }
  245. GizmosColor.Pop();
  246. GizmosMatrix.Pop();
  247. }
  248. public static void RenderLinesBetweenPoints(List<Vector3> points, Color color, Vector3 offset)
  249. {
  250. GizmosMatrix.Push(Matrix4x4.identity);
  251. GizmosColor.Push(color);
  252. int numberOfPoints = points.Count;
  253. for (int pointIndex = 0; pointIndex < numberOfPoints; ++pointIndex)
  254. {
  255. Gizmos.DrawLine(points[pointIndex] + offset, points[(pointIndex + 1) % numberOfPoints] + offset);
  256. }
  257. GizmosColor.Pop();
  258. GizmosMatrix.Pop();
  259. }
  260. public static void RenderLine(Vector3 firstPoint, Vector3 secondPoint, Color color)
  261. {
  262. GizmosMatrix.Push(Matrix4x4.identity);
  263. GizmosColor.Push(color);
  264. Gizmos.DrawLine(firstPoint, secondPoint);
  265. GizmosColor.Pop();
  266. GizmosMatrix.Pop();
  267. }
  268. #endregion
  269. #region Private Static Functions
  270. private static Mesh GetRectangleMesh()
  271. {
  272. if (_xyRectangleMesh == null) _xyRectangleMesh = Octave3DWorldBuilder.ActiveInstance.ToolResources.MeshResources.CreateXYRectangleMesh(1.0f, 1.0f, Color.white);
  273. return _xyRectangleMesh;
  274. }
  275. private static Mesh GetCircleMesh()
  276. {
  277. if (_xyCircleMesh == null) _xyCircleMesh = Octave3DWorldBuilder.ActiveInstance.ToolResources.MeshResources.CreateXYCircleMesh(1.0f, _numberOfCircleMeshSlices, Color.white);
  278. return _xyCircleMesh;
  279. }
  280. #endregion
  281. }
  282. }
  283. #endif