#if UNITY_EDITOR using UnityEngine; using System.Collections.Generic; namespace O3DWB { public static class GizmosEx { #region Private Static Variables private static Mesh _xyRectangleMesh; private static Mesh _xzRectangleMesh; private static Mesh _xyCircleMesh; private static int _numberOfCircleMeshSlices = 80; private static float _2DPointOffsetFromCamNearPlane = 0.01f; #endregion public static Mesh XZRectangleMesh { get { if (_xzRectangleMesh == null) _xzRectangleMesh = Octave3DWorldBuilder.ActiveInstance.ToolResources.MeshResources.CreateXZRectangleMesh(1.0f, 1.0f, Color.white); return _xzRectangleMesh; } } #region Public Static Functions public static void Render2DFilledSquare(Square2D square, Color color) { Render2DFilledRectangle(square.ToRectangle(), color); } public static void Render2DFilledRectangle(Rect rectangle, Color color) { Camera camera = SceneViewCamera.Camera; Transform cameraTransform = camera.transform; List rectWorldPoints = rectangle.GetWorldCornerPointsInFrontOfCamera(camera, _2DPointOffsetFromCamNearPlane); float width = (rectWorldPoints[0] - rectWorldPoints[1]).magnitude; float height = (rectWorldPoints[1] - rectWorldPoints[2]).magnitude; Vector3 rectangleWorldPosition = rectangle.GetWorldCenterPointInFrontOfCamera(camera, _2DPointOffsetFromCamNearPlane); Matrix4x4 transformMatrix = Matrix4x4.TRS(rectangleWorldPosition, cameraTransform.rotation, new Vector3(width, height, 1.0f)); RenderMesh(GetRectangleMesh(), transformMatrix, color); } public static void Render2DSquareBorderLines(Square2D square, Color color) { Render2DRectangleBorderLines(square.ToRectangle(), color); } public static void Render2DRectangleBorderLines(Rect rectangle, Color color) { Camera camera = SceneViewCamera.Camera; List rectWorldPoints = rectangle.GetWorldCornerPointsInFrontOfCamera(camera, _2DPointOffsetFromCamNearPlane); RenderLinesBetweenPoints(rectWorldPoints, color); } public static void Render2DFilledCircle(Circle2D circle, Color color) { Render2DFilledEllipse(new Ellipse2D(circle), color); } public static void Render2DFilledEllipse(Ellipse2D ellipse, Color color) { Camera camera = SceneViewCamera.Camera; Transform cameraTransform = camera.transform; List ellipseWorldPoints = ellipse.GetWorldExtentPointsInFrontOfCamera(camera, _2DPointOffsetFromCamNearPlane); float radiusX = (ellipseWorldPoints[1] - ellipseWorldPoints[3]).magnitude * 0.5f; float radiusY = (ellipseWorldPoints[0] - ellipseWorldPoints[2]).magnitude * 0.5f; Vector3 ellipseWorldPosition = ellipse.GetWorldCenterPointInFrontOfCamera(camera, _2DPointOffsetFromCamNearPlane); Matrix4x4 transformMatrix = Matrix4x4.TRS(ellipseWorldPosition, cameraTransform.rotation, new Vector3(radiusX, radiusY, 1.0f)); RenderMesh(GetCircleMesh(), transformMatrix, color); } public static void Render2DCircleBorderLines(Circle2D circle, Color color) { Ellipse2D ellipse = new Ellipse2D(circle); Render2DEllipseBorderLines(ellipse, color); } public static void Render2DEllipseBorderLines(Ellipse2D ellipse, Color color) { Camera camera = SceneViewCamera.Camera; List worldBorderPoints = ellipse.GetWorldBorderLinesInFrontOfCamera(camera, _2DPointOffsetFromCamNearPlane, _numberOfCircleMeshSlices); RenderLinesBetweenPoints(worldBorderPoints, color); } public static void RenderXZOrientedQuad(XZOrientedQuad3D orientedQuad, Color color) { GizmosMatrix.Push(orientedQuad.TransformMatrix.ToMatrix4x4x); GizmosColor.Push(color); Gizmos.DrawCube(Vector3.zero, new Vector3(orientedQuad.ModelSpaceXZSize.x, 0.0f, orientedQuad.ModelSpaceXZSize.y)); GizmosColor.Pop(); GizmosMatrix.Pop(); } public static void RenderXZOrientedQuad(XZOrientedQuad3D orientedQuad, Color color, float offsetAlongNormal) { Matrix4x4 translationMatrix = Matrix4x4.TRS(orientedQuad.Plane.normal * offsetAlongNormal, Quaternion.identity, Vector3.one); GizmosMatrix.Push(translationMatrix * orientedQuad.TransformMatrix.ToMatrix4x4x); GizmosColor.Push(color); Gizmos.DrawCube(Vector3.zero, new Vector3(orientedQuad.ModelSpaceXZSize.x, 0.0f, orientedQuad.ModelSpaceXZSize.y)); GizmosColor.Pop(); GizmosMatrix.Pop(); } public static void RenderXZOrientedQuadBorderLines(XZOrientedQuad3D orientedQuad, Color color) { RenderLinesBetweenPoints(orientedQuad.GetCornerPoints(), color); } public static void RenderXZOrientedQuadBorderLines(XZOrientedQuad3D orientedQuad, Color color, float offsetAlongNormal) { List cornerPoints = orientedQuad.GetCornerPoints(); cornerPoints = Vector3Extensions.ApplyOffsetToPoints(cornerPoints, orientedQuad.Plane.normal * offsetAlongNormal); RenderLinesBetweenPoints(cornerPoints, color); } public static void RenderOrientedBox(OrientedBox orientedBox, Color color) { Matrix4x4 transformMatrix = Matrix4x4.TRS(orientedBox.Center, orientedBox.Rotation, orientedBox.ScaledSize); GizmosMatrix.Push(transformMatrix); GizmosColor.Push(color); Gizmos.DrawCube(Vector3.zero, Vector3.one); GizmosColor.Pop(); GizmosMatrix.Pop(); } public static void RenderBoxEdges(Box box, Color color) { GizmosColor.Push(color); Gizmos.DrawWireCube(box.Center, box.Size); GizmosColor.Pop(); } public static void RenderOrientedBoxEdges(OrientedBox orientedBox, Color color) { GizmosColor.Push(color); GizmosMatrix.Push(Matrix4x4.TRS(orientedBox.Center, orientedBox.Rotation, orientedBox.ScaledSize)); Gizmos.DrawWireCube(Vector3.zero, Vector3.one); GizmosMatrix.Pop(); GizmosColor.Pop(); } public static void RenderOrientedBoxCornerEdges(OrientedBox orientedBox, float cornerEdgeLengthPercentage, Color color) { cornerEdgeLengthPercentage = Mathf.Clamp(cornerEdgeLengthPercentage, 0.0f, 1.0f); List boxCornerPoints = orientedBox.GetCenterAndCornerPoints(); GizmosColor.Push(color); // Render the corner edges along the top edge of the box's front face Segment3D segment = new Segment3D(boxCornerPoints[(int)BoxPoint.FrontTopLeft], boxCornerPoints[(int)BoxPoint.FrontTopRight]); float edgeLength = segment.HalfLength * cornerEdgeLengthPercentage; if (edgeLength > 0.0f) { Gizmos.DrawLine(segment.StartPoint, segment.StartPoint + segment.NormalizedDirection * edgeLength); Gizmos.DrawLine(segment.EndPoint, segment.EndPoint - segment.NormalizedDirection * edgeLength); } // Render the corner edges along the bottom edge of the box's front face segment = new Segment3D(boxCornerPoints[(int)BoxPoint.FrontBottomLeft], boxCornerPoints[(int)BoxPoint.FrontBottomRight]); edgeLength = segment.HalfLength * cornerEdgeLengthPercentage; if (edgeLength > 0.0f) { Gizmos.DrawLine(segment.StartPoint, segment.StartPoint + segment.NormalizedDirection * edgeLength); Gizmos.DrawLine(segment.EndPoint, segment.EndPoint - segment.NormalizedDirection * edgeLength); } // Render the corner edges along the left edge of the box's front face segment = new Segment3D(boxCornerPoints[(int)BoxPoint.FrontTopLeft], boxCornerPoints[(int)BoxPoint.FrontBottomLeft]); edgeLength = segment.HalfLength * cornerEdgeLengthPercentage; if (edgeLength > 0.0f) { Gizmos.DrawLine(segment.StartPoint, segment.StartPoint + segment.NormalizedDirection * edgeLength); Gizmos.DrawLine(segment.EndPoint, segment.EndPoint - segment.NormalizedDirection * edgeLength); } // Render the corner edges along the right edge of the box's front face segment = new Segment3D(boxCornerPoints[(int)BoxPoint.FrontTopRight], boxCornerPoints[(int)BoxPoint.FrontBottomRight]); edgeLength = segment.HalfLength * cornerEdgeLengthPercentage; if (edgeLength > 0.0f) { Gizmos.DrawLine(segment.StartPoint, segment.StartPoint + segment.NormalizedDirection * edgeLength); Gizmos.DrawLine(segment.EndPoint, segment.EndPoint - segment.NormalizedDirection * edgeLength); } // Render the corner edges along the top edge of the box's back face segment = new Segment3D(boxCornerPoints[(int)BoxPoint.BackTopLeft], boxCornerPoints[(int)BoxPoint.BackTopRight]); edgeLength = segment.HalfLength * cornerEdgeLengthPercentage; if (edgeLength > 0.0f) { Gizmos.DrawLine(segment.StartPoint, segment.StartPoint + segment.NormalizedDirection * edgeLength); Gizmos.DrawLine(segment.EndPoint, segment.EndPoint - segment.NormalizedDirection * edgeLength); } // Render the corner edges along the bottom edge of the box's back face segment = new Segment3D(boxCornerPoints[(int)BoxPoint.BackBottomLeft], boxCornerPoints[(int)BoxPoint.BackBottomRight]); edgeLength = segment.HalfLength * cornerEdgeLengthPercentage; if (edgeLength > 0.0f) { Gizmos.DrawLine(segment.StartPoint, segment.StartPoint + segment.NormalizedDirection * edgeLength); Gizmos.DrawLine(segment.EndPoint, segment.EndPoint - segment.NormalizedDirection * edgeLength); } // Render the corner edges along the left edge of the box's back face segment = new Segment3D(boxCornerPoints[(int)BoxPoint.BackTopLeft], boxCornerPoints[(int)BoxPoint.BackBottomLeft]); edgeLength = segment.HalfLength * cornerEdgeLengthPercentage; if (edgeLength > 0.0f) { Gizmos.DrawLine(segment.StartPoint, segment.StartPoint + segment.NormalizedDirection * edgeLength); Gizmos.DrawLine(segment.EndPoint, segment.EndPoint - segment.NormalizedDirection * edgeLength); } // Render the corner edges along the right edge of the box's back face segment = new Segment3D(boxCornerPoints[(int)BoxPoint.BackTopRight], boxCornerPoints[(int)BoxPoint.BackBottomRight]); edgeLength = segment.HalfLength * cornerEdgeLengthPercentage; if (edgeLength > 0.0f) { Gizmos.DrawLine(segment.StartPoint, segment.StartPoint + segment.NormalizedDirection * edgeLength); Gizmos.DrawLine(segment.EndPoint, segment.EndPoint - segment.NormalizedDirection * edgeLength); } // Render the corner edges along the left edge of the box's top face segment = new Segment3D(boxCornerPoints[(int)BoxPoint.FrontTopLeft], boxCornerPoints[(int)BoxPoint.BackTopRight]); edgeLength = segment.HalfLength * cornerEdgeLengthPercentage; if (edgeLength > 0.0f) { Gizmos.DrawLine(segment.StartPoint, segment.StartPoint + segment.NormalizedDirection * edgeLength); Gizmos.DrawLine(segment.EndPoint, segment.EndPoint - segment.NormalizedDirection * edgeLength); } // Render the corner edges along the right edge of the box's top face segment = new Segment3D(boxCornerPoints[(int)BoxPoint.FrontTopRight], boxCornerPoints[(int)BoxPoint.BackTopLeft]); edgeLength = segment.HalfLength * cornerEdgeLengthPercentage; if (edgeLength > 0.0f) { Gizmos.DrawLine(segment.StartPoint, segment.StartPoint + segment.NormalizedDirection * edgeLength); Gizmos.DrawLine(segment.EndPoint, segment.EndPoint - segment.NormalizedDirection * edgeLength); } // Render the corner edges along the left edge of the box's bottom face segment = new Segment3D(boxCornerPoints[(int)BoxPoint.FrontBottomLeft], boxCornerPoints[(int)BoxPoint.BackBottomRight]); edgeLength = segment.HalfLength * cornerEdgeLengthPercentage; if (edgeLength > 0.0f) { Gizmos.DrawLine(segment.StartPoint, segment.StartPoint + segment.NormalizedDirection * edgeLength); Gizmos.DrawLine(segment.EndPoint, segment.EndPoint - segment.NormalizedDirection * edgeLength); } // Render the corner edges along the right edge of the box's bottom face segment = new Segment3D(boxCornerPoints[(int)BoxPoint.FrontBottomRight], boxCornerPoints[(int)BoxPoint.BackBottomLeft]); edgeLength = segment.HalfLength * cornerEdgeLengthPercentage; if (edgeLength > 0.0f) { Gizmos.DrawLine(segment.StartPoint, segment.StartPoint + segment.NormalizedDirection * edgeLength); Gizmos.DrawLine(segment.EndPoint, segment.EndPoint - segment.NormalizedDirection * edgeLength); } GizmosColor.Pop(); } public static void RenderMesh(Mesh mesh, Matrix4x4 transformMatrix, Color color) { GizmosMatrix.Push(transformMatrix); GizmosColor.Push(color); Gizmos.DrawMesh(mesh); GizmosColor.Pop(); GizmosMatrix.Pop(); } public static void RenderLinesBetweenPoints(List points, Color color) { GizmosMatrix.Push(Matrix4x4.identity); GizmosColor.Push(color); int numberOfPoints = points.Count; for (int pointIndex = 0; pointIndex < numberOfPoints; ++pointIndex) { Gizmos.DrawLine(points[pointIndex], points[(pointIndex + 1) % numberOfPoints]); } GizmosColor.Pop(); GizmosMatrix.Pop(); } public static void RenderLinesBetweenPoints(List points, Color color, Vector3 offset) { GizmosMatrix.Push(Matrix4x4.identity); GizmosColor.Push(color); int numberOfPoints = points.Count; for (int pointIndex = 0; pointIndex < numberOfPoints; ++pointIndex) { Gizmos.DrawLine(points[pointIndex] + offset, points[(pointIndex + 1) % numberOfPoints] + offset); } GizmosColor.Pop(); GizmosMatrix.Pop(); } public static void RenderLine(Vector3 firstPoint, Vector3 secondPoint, Color color) { GizmosMatrix.Push(Matrix4x4.identity); GizmosColor.Push(color); Gizmos.DrawLine(firstPoint, secondPoint); GizmosColor.Pop(); GizmosMatrix.Pop(); } #endregion #region Private Static Functions private static Mesh GetRectangleMesh() { if (_xyRectangleMesh == null) _xyRectangleMesh = Octave3DWorldBuilder.ActiveInstance.ToolResources.MeshResources.CreateXYRectangleMesh(1.0f, 1.0f, Color.white); return _xyRectangleMesh; } private static Mesh GetCircleMesh() { if (_xyCircleMesh == null) _xyCircleMesh = Octave3DWorldBuilder.ActiveInstance.ToolResources.MeshResources.CreateXYCircleMesh(1.0f, _numberOfCircleMeshSlices, Color.white); return _xyCircleMesh; } #endregion } } #endif