/** A commerical class which should not be public. Use PEDraw instead. **/ using UnityEngine; using System.Collections; using System.Collections.Generic; namespace Ximmerse.XR.Utils { internal static class UltiDraw { public static Color White = Color.white; public static Color Black = Color.black; public static Color Red = Color.red; public static Color DarkRed = new Color(0.75f, 0f, 0f, 1f); public static Color Green = Color.green; public static Color DarkGreen = new Color(0f, 0.75f, 0f, 1f); public static Color Blue = Color.blue; public static Color Cyan = Color.cyan; public static Color Magenta = Color.magenta; public static Color Yellow = Color.yellow; public static Color Grey = Color.grey; public static Color LightGrey = new Color(0.75f, 0.75f, 0.75f, 1f); public static Color DarkGrey = new Color(0.25f, 0.25f, 0.25f, 1f); public static Color Orange = new Color(1f, 0.5f, 0f, 1f); public static Color Brown = new Color(0.5f, 0.25f, 0f, 1f); public static Color Mustard = new Color(1f, 0.75f, 0.25f, 1f); public static Color Teal = new Color(0f, 0.75f, 0.75f, 1f); public static Color Purple = new Color(0.5f, 0f, 0.5f, 1f); private static int Resolution = 30; private static Mesh Initialised; private static bool Active; private static Material GLMaterial; private static Material MeshMaterial; public static Material CustomMaterial; public static int CustomMaterialPass; private static float GUIOffset = 0.001f; private static Camera Camera; private static Vector3 ViewPosition; private static Quaternion ViewRotation; private static PROGRAM Program = PROGRAM.NONE; private enum PROGRAM { NONE, LINES, TRIANGLES, TRIANGLE_STRIP, QUADS} ; private static Mesh CircleMesh; private static Mesh QuadMesh; private static Mesh CubeMesh; private static Mesh SphereMesh; private static Mesh CylinderMesh; private static Mesh CapsuleMesh; private static Mesh ConeMesh; private static Mesh PyramidMesh; private static Mesh BoneMesh; private static Mesh PlaneMesh; private static Vector3[] CircleWire; private static Vector3[] QuadWire; private static Vector3[] CubeWire; private static Vector3[] SphereWire; private static Vector3[] CylinderWire; private static Vector3[] CapsuleWire; private static Vector3[] ConeWire; private static Vector3[] PyramidWire; private static Vector3[] BoneWire; private static Vector3[] PlaneWire; /// /// Should be called each time before actual drawing. /// Return false for fail drawing. /// public static bool Begin() { if (Active) { Debug.Log("Drawing is still active. Call 'End()' to stop."); return true; } else { Initialise(); Camera = GetCamera(); if(Camera != null) { ViewPosition = Camera.transform.position; ViewRotation = Camera.transform.rotation; Active = true; return true; } else { return false; } } } public static void End() { if (Active) { SetProgram(PROGRAM.NONE); Camera = null; ViewPosition = Vector3.zero; ViewRotation = Quaternion.identity; Active = false; } // else // { // Debug.Log("Drawing is not active. Call 'Begin()' to start."); // } } public static void SetDepthRendering(bool enabled) { Initialise(); SetProgram(PROGRAM.NONE); GLMaterial.SetInt("_ZWrite", enabled ? 1 : 0); GLMaterial.SetInt("_ZTest", enabled ? (int)UnityEngine.Rendering.CompareFunction.LessEqual : (int)UnityEngine.Rendering.CompareFunction.Always); MeshMaterial.SetInt("_ZWrite", enabled ? 1 : 0); MeshMaterial.SetInt("_ZTest", enabled ? (int)UnityEngine.Rendering.CompareFunction.LessEqual : (int)UnityEngine.Rendering.CompareFunction.Always); } public static void SetCurvature(float value) { Initialise(); SetProgram(PROGRAM.NONE); MeshMaterial.SetFloat("_Power", value); } public static void SetFilling(float value) { value = Mathf.Clamp(value, 0f, 1f); Initialise(); SetProgram(PROGRAM.NONE); MeshMaterial.SetFloat("_Filling", value); } //------------------------------------------------------------------------------------------ //2D SCENE DRAWING FUNCTIONS //------------------------------------------------------------------------------------------ public static void DrawLine(Vector3 start, Vector3 end, Color color) { if (Return()) { return; } ; SetProgram(PROGRAM.LINES); GL.Color(color); GL.Vertex(start); GL.Vertex(end); } public static void DrawLine(Vector3 start, Vector3 end, float thickness, Color color) { DrawLine(start, end, thickness, thickness, color); } public static void DrawLine(Vector3 start, Vector3 end, float startThickness, float endThickness, Color color) { if (Return()) { return; } ; SetProgram(PROGRAM.QUADS); GL.Color(color); Vector3 dir = (end - start).normalized; Vector3 orthoStart = startThickness / 2f * (Quaternion.AngleAxis(90f, (start - ViewPosition)) * dir); Vector3 orthoEnd = endThickness / 2f * (Quaternion.AngleAxis(90f, (end - ViewPosition)) * dir); GL.Vertex(end + orthoEnd); GL.Vertex(end - orthoEnd); GL.Vertex(start - orthoStart); GL.Vertex(start + orthoStart); } public static void DrawTriangle(Vector3 a, Vector3 b, Vector3 c, Color color) { if (Return()) { return; } ; SetProgram(PROGRAM.TRIANGLES); GL.Color(color); GL.Vertex(b); GL.Vertex(a); GL.Vertex(c); } public static void DrawTriangleWire(Vector3 a, Vector3 b, Vector3 c, Color color) { if (Return()) { return; } ; SetProgram(PROGRAM.LINES); GL.Color(color); GL.Vertex(a); GL.Vertex(b); GL.Vertex(b); GL.Vertex(c); GL.Vertex(c); GL.Vertex(a); } public static void DrawCircle(Vector3 position, float size, Color color) { DrawMesh(CircleMesh, position, ViewRotation, size * Vector3.one, color); } public static void DrawCircle(Vector3 position, Quaternion rotation, float size, Color color) { DrawMesh(CircleMesh, position, rotation, size * Vector3.one, color); } public static void DrawWireCircle(Vector3 position, float size, Color color) { DrawWire(CircleWire, position, ViewRotation, size * Vector3.one, color); } public static void DrawWireCircle(Vector3 position, Quaternion rotation, float size, Color color) { DrawWire(CircleWire, position, rotation, size * Vector3.one, color); } public static void DrawWiredCircle(Vector3 position, float size, Color circleColor, Color wireColor) { DrawCircle(position, size, circleColor); DrawWireCircle(position, size, wireColor); } public static void DrawWiredCircle(Vector3 position, Quaternion rotation, float size, Color circleColor, Color wireColor) { DrawCircle(position, rotation, size, circleColor); DrawWireCircle(position, rotation, size, wireColor); } public static void DrawEllipse(Vector3 position, float width, float height, Color color) { DrawMesh(CircleMesh, position, ViewRotation, new Vector3(width, height, 1f), color); } public static void DrawEllipse(Vector3 position, Quaternion rotation, float width, float height, Color color) { DrawMesh(CircleMesh, position, rotation, new Vector3(width, height, 1f), color); } public static void DrawWireEllipse(Vector3 position, float width, float height, Color color) { DrawWire(CircleWire, position, ViewRotation, new Vector3(width, height, 1f), color); } public static void DrawWireEllipse(Vector3 position, Quaternion rotation, float width, float height, Color color) { DrawWire(CircleWire, position, rotation, new Vector3(width, height, 1f), color); } public static void DrawWiredEllipse(Vector3 position, float width, float height, Color ellipseColor, Color wireColor) { DrawEllipse(position, ViewRotation, width, height, ellipseColor); DrawWireEllipse(position, ViewRotation, width, height, wireColor); } public static void DrawWiredEllipse(Vector3 position, Quaternion rotation, float width, float height, Color ellipseColor, Color wireColor) { DrawEllipse(position, rotation, width, height, ellipseColor); DrawWireEllipse(position, rotation, width, height, wireColor); } public static void DrawArrow(Vector3 start, Vector3 end, float tipPivot, float shaftWidth, float tipWidth, Color color) { tipPivot = Mathf.Clamp(tipPivot, 0f, 1f); Vector3 pivot = start + tipPivot * (end - start); DrawLine(start, pivot, shaftWidth, color); DrawLine(pivot, end, tipWidth, 0f, color); } public static void DrawArrow(Vector3 start, Vector3 end, float tipPivot, float shaftWidth, float tipWidth, Color shaftColor, Color tipColor) { tipPivot = Mathf.Clamp(tipPivot, 0f, 1f); Vector3 pivot = start + tipPivot * (end - start); DrawLine(start, pivot, shaftWidth, shaftColor); DrawLine(pivot, end, tipWidth, 0f, tipColor); } public static void DrawGrid(Vector3 center, Quaternion rotation, int cellsX, int cellsY, float sizeX, float sizeY, Color color) { if (Return()) { return; } float width = cellsX * sizeX; float height = cellsY * sizeY; Vector3 start = center - width / 2f * (rotation * Vector3.right) - height / 2f * (rotation * Vector3.forward); Vector3 dirX = rotation * Vector3.right; Vector3 dirY = rotation * Vector3.forward; for (int i = 0; i < cellsX + 1; i++) { DrawLine(start + i * sizeX * dirX, start + i * sizeX * dirX + height * dirY, color); } for (int i = 0; i < cellsY + 1; i++) { DrawLine(start + i * sizeY * dirY, start + i * sizeY * dirY + width * dirX, color); } } /// /// Draws the grid from origin point, where center, rotation is the left bottom point of the grid. /// /// Center. /// Rotation. /// Cells x. /// Cells y. /// Size x. /// Size y. /// Color. public static void DrawGridLBOrigin(Vector3 center, Quaternion rotation, int cellsX, int cellsY, float sizeX, float sizeY, Color color) { if (Return()) { return; } float width = cellsX * sizeX; float height = cellsY * sizeY; Vector3 start = center; Vector3 dirX = rotation * Vector3.right; Vector3 dirY = rotation * Vector3.forward; for (int i = 0; i < cellsX + 1; i++) { DrawLine(start + i * sizeX * dirX, start + i * sizeX * dirX + height * dirY, color); } for (int i = 0; i < cellsY + 1; i++) { DrawLine(start + i * sizeY * dirY, start + i * sizeY * dirY + width * dirX, color); } } /// /// Draws the grid from origin point, where center, rotation is the right top point of the grid. /// /// Center. /// Rotation. /// Cells x. /// Cells y. /// Size x. /// Size y. /// Color. public static void DrawGridRTOrigin(Vector3 center, Quaternion rotation, int cellsX, int cellsY, float sizeX, float sizeY, Color color) { if (Return()) { return; } float width = cellsX * sizeX; float height = cellsY * sizeY; Vector3 start = center; Vector3 dirX = rotation * Vector3.left; Vector3 dirY = rotation * -Vector3.forward; for (int i = 0; i < cellsX + 1; i++) { DrawLine(start + i * sizeX * dirX, start + i * sizeX * dirX + height * dirY, color); } for (int i = 0; i < cellsY + 1; i++) { DrawLine(start + i * sizeY * dirY, start + i * sizeY * dirY + width * dirX, color); } } public static void DrawQuad(Vector3 position, Quaternion rotation, float width, float height, Color color) { DrawMesh(QuadMesh, position, rotation, new Vector3(width, height, 1f), color); } public static void DrawWireQuad(Vector3 position, Quaternion rotation, float width, float height, Color color) { DrawWire(QuadWire, position, rotation, new Vector3(width, height, 1f), color); } public static void DrawWiredQuad(Vector3 position, Quaternion rotation, float width, float height, Color quadColor, Color wireColor) { DrawQuad(position, rotation, width, height, quadColor); DrawWireQuad(position, rotation, width, height, wireColor); } public static void DrawPlane(Vector3 position, Quaternion rotation, float width, float height, Color color) { DrawMesh(PlaneMesh, position, rotation, new Vector3(width / 10, 1, height / 10), color); } public static void DrawWirePlane(Vector3 position, Quaternion rotation, float width, float height, Color color) { DrawWire(PlaneWire, position, rotation, new Vector3(width, 1, height), color); } public static void DrawWiredPlane(Vector3 position, Quaternion rotation, float width, float height, Color color, Color wiredColor) { DrawWire(PlaneWire, position, rotation, new Vector3(width, 1, height), wiredColor); DrawMesh(PlaneMesh, position, rotation, new Vector3(width / 10, 1, height / 10), color); } public static void DrawCube(Vector3 position, Quaternion rotation, float size, Color color) { DrawMesh(CubeMesh, position, rotation, size * Vector3.one, color); } public static void DrawWireCube(Vector3 position, Quaternion rotation, float size, Color color) { DrawWire(CubeWire, position, rotation, size * Vector3.one, color); } public static void DrawWiredCube(Vector3 position, Quaternion rotation, float size, Color cubeColor, Color wireColor) { DrawCube(position, rotation, size, cubeColor); DrawWireCube(position, rotation, size, wireColor); } public static void DrawCuboid(Vector3 position, Quaternion rotation, Vector3 size, Color color) { DrawMesh(CubeMesh, position, rotation, size, color); } public static void DrawWireCuboid(Vector3 position, Quaternion rotation, Vector3 size, Color color) { DrawWire(CubeWire, position, rotation, size, color); } public static void DrawWiredCuboid(Vector3 position, Quaternion rotation, Vector3 size, Color cuboidColor, Color wireColor) { DrawCuboid(position, rotation, size, cuboidColor); DrawWireCuboid(position, rotation, size, wireColor); } public static void DrawSphere(Vector3 position, Quaternion rotation, float size, Color color) { DrawMesh(SphereMesh, position, rotation, size * Vector3.one, color); } public static void DrawWireSphere(Vector3 position, Quaternion rotation, float size, Color color) { DrawWire(SphereWire, position, rotation, size * Vector3.one, color); } public static void DrawWiredSphere(Vector3 position, Quaternion rotation, float size, Color sphereColor, Color wireColor) { DrawSphere(position, rotation, size, sphereColor); DrawWireSphere(position, rotation, size, wireColor); } public static void DrawEllipsoid(Vector3 position, Quaternion rotation, float width, float height, Color color) { DrawMesh(SphereMesh, position, rotation, new Vector3(width, height, width), color); } public static void DrawWireEllipsoid(Vector3 position, Quaternion rotation, float width, float height, Color color) { DrawWire(SphereWire, position, rotation, new Vector3(width, height, width), color); } public static void DrawWiredEllipsoid(Vector3 position, Quaternion rotation, float width, float height, Color ellipsoidColor, Color wireColor) { DrawEllipsoid(position, rotation, width, height, ellipsoidColor); DrawWireEllipsoid(position, rotation, width, height, wireColor); } public static void DrawCylinder(Vector3 position, Quaternion rotation, float width, float height, Color color) { DrawMesh(CylinderMesh, position, rotation, new Vector3(width, height / 2f, width), color); } public static void DrawWireCylinder(Vector3 position, Quaternion rotation, float width, float height, Color color) { DrawWire(CylinderWire, position, rotation, new Vector3(width, height / 2f, width), color); } public static void DrawWiredCylinder(Vector3 position, Quaternion rotation, float width, float height, Color cylinderColor, Color wireColor) { DrawCylinder(position, rotation, width, height, cylinderColor); DrawWireCylinder(position, rotation, width, height, wireColor); } public static void DrawCapsule(Vector3 position, Quaternion rotation, float width, float height, Color color) { DrawMesh(CapsuleMesh, position, rotation, new Vector3(width, height / 2f, width), color); } public static void DrawWireCapsule(Vector3 position, Quaternion rotation, float width, float height, Color color) { DrawWire(CapsuleWire, position, rotation, new Vector3(width, height / 2f, width), color); } public static void DrawWiredCapsule(Vector3 position, Quaternion rotation, float width, float height, Color capsuleColor, Color wireColor) { DrawCapsule(position, rotation, width, height, capsuleColor); DrawWireCapsule(position, rotation, width, height, wireColor); } public static void DrawCone(Vector3 position, Quaternion rotation, float width, float height, Color color) { DrawMesh(ConeMesh, position, rotation, new Vector3(width, height, width), color); } public static void DrawWireCone(Vector3 position, Quaternion rotation, float width, float height, Color color) { DrawWire(ConeWire, position, rotation, new Vector3(width, height, width), color); } public static void DrawWiredCone(Vector3 position, Quaternion rotation, float width, float height, Color coneColor, Color wireColor) { DrawCone(position, rotation, width, height, coneColor); DrawWireCone(position, rotation, width, height, wireColor); } public static void DrawPyramid(Vector3 position, Quaternion rotation, float width, float height, Color color) { DrawMesh(PyramidMesh, position, rotation, new Vector3(width, height, width), color); } public static void DrawWirePyramid(Vector3 position, Quaternion rotation, float width, float height, Color color) { DrawWire(PyramidWire, position, rotation, new Vector3(width, height, width), color); } public static void DrawWiredPyramid(Vector3 position, Quaternion rotation, float width, float height, Color pyramidColor, Color wireColor) { DrawPyramid(position, rotation, width, height, pyramidColor); DrawWirePyramid(position, rotation, width, height, wireColor); } public static void DrawBone(Vector3 position, Quaternion rotation, float width, float length, Color color) { DrawMesh(BoneMesh, position, rotation, new Vector3(width, width, length), color); } public static void DrawWireBone(Vector3 position, Quaternion rotation, float width, float length, Color color) { DrawWire(BoneWire, position, rotation, new Vector3(width, width, length), color); } public static void DrawWiredBone(Vector3 position, Quaternion rotation, float width, float length, Color boneColor, Color wireColor) { DrawBone(position, rotation, width, length, boneColor); DrawWireBone(position, rotation, width, length, wireColor); } public static void DrawTranslateGizmo(Vector3 position, Quaternion rotation, float size) { if (Return()) { return; } DrawLine(position, position + 0.8f * size * (rotation * Vector3.right), Red); DrawCone(position + 0.8f * size * (rotation * Vector3.right), rotation * Quaternion.Euler(0f, 0f, -90f), 0.15f * size, 0.2f * size, Red); DrawLine(position, position + 0.8f * size * (rotation * Vector3.up), Green); DrawCone(position + 0.8f * size * (rotation * Vector3.up), rotation * Quaternion.Euler(0f, 0f, 0f), 0.15f * size, 0.2f * size, Green); DrawLine(position, position + 0.8f * size * (rotation * Vector3.forward), Blue); DrawCone(position + 0.8f * size * (rotation * Vector3.forward), rotation * Quaternion.Euler(90f, 0f, 0f), 0.15f * size, 0.2f * size, Blue); } public static void DrawRotateGizmo(Vector3 position, Quaternion rotation, float size) { if (Return()) { return; } SetProgram(PROGRAM.NONE); DrawWireCircle(position, rotation * Quaternion.Euler(0f, 90f, 0f), 2f * size, Red); SetProgram(PROGRAM.NONE); DrawWireCircle(position, rotation * Quaternion.Euler(90f, 0f, 90f), 2f * size, Green); SetProgram(PROGRAM.NONE); DrawWireCircle(position, rotation * Quaternion.Euler(0f, 0f, 0f), 2f * size, Blue); SetProgram(PROGRAM.NONE); } public static void DrawScaleGizmo(Vector3 position, Quaternion rotation, float size) { if (Return()) { return; } DrawLine(position, position + 0.85f * size * (rotation * Vector3.right), Red); DrawCube(position + 0.925f * size * (rotation * Vector3.right), rotation, 0.15f, Red); DrawLine(position, position + 0.85f * size * (rotation * Vector3.up), Green); DrawCube(position + 0.925f * size * (rotation * Vector3.up), rotation, 0.15f, Green); DrawLine(position, position + 0.85f * size * (rotation * Vector3.forward), Blue); DrawCube(position + 0.925f * size * (rotation * Vector3.forward), rotation, 0.15f, Blue); } public static void DrawMesh(Mesh mesh, Vector3 position, Quaternion rotation, Vector3 scale, Color color) { if (Return()) { return; } SetProgram(PROGRAM.NONE); if(CustomMaterial != null) { CustomMaterial.color = color; CustomMaterial.SetPass (CustomMaterialPass); } else { MeshMaterial.color = color; MeshMaterial.SetPass(0); } Graphics.DrawMeshNow(mesh, Matrix4x4.TRS(position, rotation, scale)); } //------------------------------------------------------------------------------------------ //GUI DRAWING FUNCTIONS //------------------------------------------------------------------------------------------ public static void DrawGUILine(Vector2 start, Vector2 end, Color color) { if (Camera != Camera.main) { return; } if (Return()) { return; } SetProgram(PROGRAM.LINES); GL.Color(color); start.x *= Screen.width; start.y *= Screen.height; end.x *= Screen.width; end.y *= Screen.height; GL.Vertex(Camera.ScreenToWorldPoint(new Vector3(start.x, start.y, Camera.nearClipPlane + GUIOffset))); GL.Vertex(Camera.ScreenToWorldPoint(new Vector3(end.x, end.y, Camera.nearClipPlane + GUIOffset))); } public static void DrawGUILine(Vector2 start, Vector2 end, float thickness, Color color) { if (Camera != Camera.main) { return; } if (Return()) { return; } SetProgram(PROGRAM.QUADS); GL.Color(color); start.x *= Screen.width; start.y *= Screen.height; end.x *= Screen.width; end.y *= Screen.height; thickness *= Screen.width; Vector3 p1 = new Vector3(start.x, start.y, Camera.nearClipPlane + GUIOffset); Vector3 p2 = new Vector3(end.x, end.y, Camera.nearClipPlane + GUIOffset); Vector3 dir = end - start; Vector3 ortho = thickness / 2f * (Quaternion.AngleAxis(90f, Vector3.forward) * dir).normalized; GL.Vertex(Camera.ScreenToWorldPoint(p1 - ortho)); GL.Vertex(Camera.ScreenToWorldPoint(p1 + ortho)); GL.Vertex(Camera.ScreenToWorldPoint(p2 + ortho)); GL.Vertex(Camera.ScreenToWorldPoint(p2 - ortho)); } public static void DrawGUIRectangle(Vector2 center, Vector2 size, Color color) { if (Camera != Camera.main) { return; } if (Return()) { return; } SetProgram(PROGRAM.QUADS); GL.Color(color); center.x *= Screen.width; center.y *= Screen.height; size.x *= Screen.width; size.y *= Screen.height; GL.Vertex(Camera.ScreenToWorldPoint(new Vector3(center.x + size.x / 2f, center.y - size.y / 2f, Camera.nearClipPlane + GUIOffset))); GL.Vertex(Camera.ScreenToWorldPoint(new Vector3(center.x - size.x / 2f, center.y - size.y / 2f, Camera.nearClipPlane + GUIOffset))); GL.Vertex(Camera.ScreenToWorldPoint(new Vector3(center.x + -size.x / 2f, center.y + size.y / 2f, Camera.nearClipPlane + GUIOffset))); GL.Vertex(Camera.ScreenToWorldPoint(new Vector3(center.x + size.x / 2f, center.y + size.y / 2f, Camera.nearClipPlane + GUIOffset))); } public static void DrawGUITriangle(Vector2 a, Vector2 b, Vector2 c, Color color) { if (Camera != Camera.main) { return; } if (Return()) { return; } SetProgram(PROGRAM.TRIANGLES); GL.Color(color); a.x *= Screen.width; a.y *= Screen.height; b.x *= Screen.width; b.y *= Screen.height; c.x *= Screen.width; c.y *= Screen.height; GL.Vertex(Camera.ScreenToWorldPoint(new Vector3(a.x, a.y, Camera.nearClipPlane + GUIOffset))); GL.Vertex(Camera.ScreenToWorldPoint(new Vector3(b.x, b.y, Camera.nearClipPlane + GUIOffset))); GL.Vertex(Camera.ScreenToWorldPoint(new Vector3(c.x, c.y, Camera.nearClipPlane + GUIOffset))); } public static void DrawGUICircle(Vector2 center, float size, Color color, Camera targetCamera) { if(targetCamera != null && Camera != targetCamera) { return; } if (targetCamera == null &&Camera != Camera.main) { return; } if (Return()) { return; } // SetProgram(PROGRAM.TRIANGLE_STRIP); // GL.Color(color); // center.x *= Screen.width; // center.y *= Screen.height; // for (int i = 0; i < CircleWire.Length; i++) // { // GL.Vertex(Camera.ScreenToWorldPoint(new Vector3(center.x + size * CircleWire [i].x * Screen.width, center.y + size * CircleWire [i].y * Screen.width, Camera.nearClipPlane + GUIOffset))); // GL.Vertex(Camera.ScreenToWorldPoint(new Vector3(center.x, center.y, Camera.nearClipPlane + GUIOffset))); // } SetProgram(PROGRAM.TRIANGLES); GL.Color(color); center.x *= Screen.width; center.y *= Screen.height; for(int i=0; i values, float yMin, float yMax, Color background, Color[] lines) { DrawGUIRectangle(center, size, background); float x = center.x - size.x / 2f; float y = center.y - size.y / 2f; float scale = yMax - yMin; for (int k = 0; k < values.Count; k++) { for (int i = 0; i < values [k].Length - 1; i++) { DrawGUILine( new Vector2(x + (float)i / (float)(values [k].Length - 1) * size.x, y + Mathf.Clamp(values [k] [i] / scale, 0f, 1f) * size.y), new Vector2(x + (float)(i + 1) / (float)(values [k].Length - 1) * size.x, y + Mathf.Clamp(values [k] [i + 1] / scale, 0f, 1f) * size.y), lines [k] ); } } } public static void DrawFunctions(Vector2 center, Vector2 size, List values, float yMin, float yMax, float thickness, Color background, Color[] lines) { DrawGUIRectangle(center, size, background); float x = center.x - size.x / 2f; float y = center.y - size.y / 2f; float scale = yMax - yMin; for (int k = 0; k < values.Count; k++) { for (int i = 0; i < values [k].Length - 1; i++) { DrawGUILine( new Vector2(x + (float)i / (float)(values [k].Length - 1) * size.x, y + Mathf.Clamp(values [k] [i] / scale, 0f, 1f) * size.y), new Vector2(x + (float)(i + 1) / (float)(values [k].Length - 1) * size.x, y + Mathf.Clamp(values [k] [i + 1] / scale, 0f, 1f) * size.y), thickness, lines [k] ); } } } //------------------------------------------------------------------------------------------ //UTILITY FUNCTIONS //------------------------------------------------------------------------------------------ private static bool Return() { // if (!Active) // { // Debug.Log("Drawing is not active. Call 'Begin()' first."); // } return !Active; } static void Initialise() { if (Initialised != null) { return; } GLMaterial = new Material(Shader.Find("Hidden/Internal-Colored")); GLMaterial.hideFlags = HideFlags.HideAndDontSave; GLMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); GLMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); GLMaterial.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Back); GLMaterial.SetInt("_ZWrite", 1); GLMaterial.SetInt("_ZTest", (int)UnityEngine.Rendering.CompareFunction.Always); Shader ultiDrawShader = Resources.Load("Tag/Material/RxDraw"); if (ultiDrawShader == null) { throw new UnityException("RxDraw.shader not in Resources folder.Call Tools/PolyEngine/PEDraw/Save Shader."); } MeshMaterial = new Material(ultiDrawShader); MeshMaterial.hideFlags = HideFlags.HideAndDontSave; MeshMaterial.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Back); MeshMaterial.SetInt("_ZWrite", 1); MeshMaterial.SetInt("_ZTest", (int)UnityEngine.Rendering.CompareFunction.Always); MeshMaterial.SetFloat("_Power", 0.25f); //Meshes CircleMesh = CreateCircleMesh(Resolution); QuadMesh = GetPrimitiveMesh(PrimitiveType.Quad); CubeMesh = GetPrimitiveMesh(PrimitiveType.Cube); SphereMesh = GetPrimitiveMesh(PrimitiveType.Sphere); CylinderMesh = GetPrimitiveMesh(PrimitiveType.Cylinder); CapsuleMesh = GetPrimitiveMesh(PrimitiveType.Capsule); PlaneMesh = GetPrimitiveMesh(PrimitiveType.Plane); ConeMesh = CreateConeMesh(Resolution); PyramidMesh = CreatePyramidMesh(); BoneMesh = CreateBoneMesh(); // //Wires CircleWire = CreateCircleWire(Resolution); QuadWire = CreateQuadWire(); CubeWire = CreateCubeWire(); SphereWire = CreateSphereWire(Resolution); CylinderWire = CreateCylinderWire(Resolution); CapsuleWire = CreateCapsuleWire(Resolution); ConeWire = CreateConeWire(Resolution); PyramidWire = CreatePyramidWire(); BoneWire = CreateBoneWire(); PlaneWire = CreatePlaneWire(); // Initialised = new Mesh(); } private static void SetProgram(PROGRAM program) { if (Program != program) { Program = program; GL.End(); if (Program != PROGRAM.NONE) { GLMaterial.SetPass(0); switch (Program) { case PROGRAM.LINES: GL.Begin(GL.LINES); break; case PROGRAM.TRIANGLES: GL.Begin(GL.TRIANGLES); break; case PROGRAM.TRIANGLE_STRIP: GL.Begin(GL.TRIANGLE_STRIP); break; case PROGRAM.QUADS: GL.Begin(GL.QUADS); break; } } } } private static void DrawWire(Vector3[] points, Vector3 position, Quaternion rotation, Vector3 scale, Color color) { if (Return()) { return; } ; SetProgram(PROGRAM.LINES); GL.Color(color); for (int i = 0; i < points.Length; i += 2) { GL.Vertex(position + rotation * Vector3.Scale(scale, points [i])); GL.Vertex(position + rotation * Vector3.Scale(scale, points [i + 1])); } } static Camera sMainCamera; private static Camera GetCamera() { if (Camera.current != null) { return Camera.current; } else if(sMainCamera != null) { return sMainCamera; } else { var mainCam = Camera.main; if(mainCam != null) { sMainCamera = mainCam; return mainCam; } else { return null; } } } private static Mesh GetPrimitiveMesh(PrimitiveType type) { GameObject gameObject = GameObject.CreatePrimitive(type); gameObject.hideFlags = HideFlags.HideInHierarchy; gameObject.GetComponent().enabled = false; Mesh mesh = gameObject.GetComponent().sharedMesh; if (Application.isPlaying) { GameObject.Destroy(gameObject); } else { GameObject.DestroyImmediate(gameObject); } return mesh; } private static Mesh CreateCircleMesh(int resolution) { List vertices = new List(); List triangles = new List(); float step = 360.0f / (float)resolution; Quaternion quaternion = Quaternion.Euler(0f, 0f, step); vertices.Add(new Vector3(0f, 0f, 0f)); vertices.Add(new Vector3(0f, 0.5f, 0f)); vertices.Add(quaternion * vertices [1]); triangles.Add(1); triangles.Add(0); triangles.Add(2); for (int i = 0; i < resolution - 1; i++) { triangles.Add(vertices.Count - 1); triangles.Add(0); triangles.Add(vertices.Count); vertices.Add(quaternion * vertices [vertices.Count - 1]); } Mesh mesh = new Mesh(); mesh.vertices = vertices.ToArray(); mesh.triangles = triangles.ToArray(); return mesh; } private static Mesh CreateConeMesh(int resolution) { List vertices = new List(); List triangles = new List(); float step = 360.0f / (float)resolution; Quaternion quaternion = Quaternion.Euler(0f, step, 0f); vertices.Add(new Vector3(0f, 1f, 0f)); vertices.Add(new Vector3(0f, 0f, 0f)); vertices.Add(new Vector3(0f, 0f, 0.5f)); vertices.Add(quaternion * vertices [2]); triangles.Add(2); triangles.Add(1); triangles.Add(3); triangles.Add(2); triangles.Add(3); triangles.Add(0); for (int i = 0; i < resolution - 1; i++) { triangles.Add(vertices.Count - 1); triangles.Add(1); triangles.Add(vertices.Count); triangles.Add(vertices.Count - 1); triangles.Add(vertices.Count); triangles.Add(0); vertices.Add(quaternion * vertices [vertices.Count - 1]); } Mesh mesh = new Mesh(); mesh.vertices = vertices.ToArray(); mesh.triangles = triangles.ToArray(); mesh.RecalculateNormals(); return mesh; } private static Mesh CreatePyramidMesh() { List vertices = new List(); List triangles = new List(); vertices.Add(new Vector3(-0.5f, 0f, -0.5f)); vertices.Add(new Vector3(0.5f, 0f, -0.5f)); vertices.Add(new Vector3(0.5f, 0f, 0.5f)); vertices.Add(new Vector3(-0.5f, 0f, -0.5f)); vertices.Add(new Vector3(0.5f, 0f, 0.5f)); vertices.Add(new Vector3(-0.5f, 0f, 0.5f)); vertices.Add(new Vector3(-0.5f, 0f, -0.5f)); vertices.Add(new Vector3(0f, 1f, 0f)); vertices.Add(new Vector3(0.5f, 0f, -0.5f)); vertices.Add(new Vector3(0.5f, 0f, -0.5f)); vertices.Add(new Vector3(0f, 1f, 0f)); vertices.Add(new Vector3(0.5f, 0f, 0.5f)); vertices.Add(new Vector3(0.5f, 0f, 0.5f)); vertices.Add(new Vector3(0f, 1f, 0f)); vertices.Add(new Vector3(-0.5f, 0f, 0.5f)); vertices.Add(new Vector3(-0.5f, 0f, 0.5f)); vertices.Add(new Vector3(0f, 1f, 0f)); vertices.Add(new Vector3(-0.5f, 0f, -0.5f)); for (int i = 0; i < 18; i++) { triangles.Add(i); } Mesh mesh = new Mesh(); mesh.vertices = vertices.ToArray(); mesh.triangles = triangles.ToArray(); mesh.RecalculateNormals(); return mesh; } private static Mesh CreateBoneMesh() { float size = 1f / 7f; List vertices = new List(); List triangles = new List(); vertices.Add(new Vector3(-size, -size, 0.200f)); vertices.Add(new Vector3(-size, size, 0.200f)); vertices.Add(new Vector3(0.000f, 0.000f, 0.000f)); vertices.Add(new Vector3(size, size, 0.200f)); vertices.Add(new Vector3(0.000f, 0.000f, 1.000f)); vertices.Add(new Vector3(size, -size, 0.200f)); vertices.Add(new Vector3(-size, size, 0.200f)); vertices.Add(new Vector3(-size, -size, 0.200f)); vertices.Add(new Vector3(0.000f, 0.000f, 1.000f)); vertices.Add(new Vector3(size, -size, 0.200f)); vertices.Add(new Vector3(0.000f, 0.000f, 1.000f)); vertices.Add(new Vector3(-size, -size, 0.200f)); vertices.Add(new Vector3(size, size, 0.200f)); vertices.Add(new Vector3(-size, size, 0.200f)); vertices.Add(new Vector3(0.000f, 0.000f, 1.000f)); vertices.Add(new Vector3(size, size, 0.200f)); vertices.Add(new Vector3(size, -size, 0.200f)); vertices.Add(new Vector3(0.000f, 0.000f, 0.000f)); vertices.Add(new Vector3(size, size, 0.200f)); vertices.Add(new Vector3(0.000f, 0.000f, 0.000f)); vertices.Add(new Vector3(-size, size, 0.200f)); vertices.Add(new Vector3(size, -size, 0.200f)); vertices.Add(new Vector3(-size, -size, 0.200f)); vertices.Add(new Vector3(0.000f, 0.000f, 0.000f)); for (int i = 0; i < 24; i++) { triangles.Add(i); } Mesh mesh = new Mesh(); mesh.vertices = vertices.ToArray(); mesh.triangles = triangles.ToArray(); mesh.RecalculateNormals(); return mesh; } private static Vector3[] CreateCircleWire(int resolution) { List points = new List(); float step = 360.0f / (float)resolution; for (int i = 0; i < resolution; i++) { points.Add(Quaternion.Euler(0f, 0f, i * step) * new Vector3(0f, 0.5f, 0f)); points.Add(Quaternion.Euler(0f, 0f, (i + 1) * step) * new Vector3(0f, 0.5f, 0f)); } return points.ToArray(); } private static Vector3[] CreateQuadWire() { List points = new List(); points.Add(new Vector3(-0.5f, -0.5f, 0f)); points.Add(new Vector3(0.5f, -0.5f, 0f)); points.Add(new Vector3(0.5f, -0.5f, 0f)); points.Add(new Vector3(0.5f, 0.5f, 0f)); points.Add(new Vector3(0.5f, 0.5f, 0f)); points.Add(new Vector3(-0.5f, 0.5f, 0f)); points.Add(new Vector3(-0.5f, 0.5f, 0f)); points.Add(new Vector3(-0.5f, -0.5f, 0f)); return points.ToArray(); } private static Vector3[] CreatePlaneWire() { List points = new List(); points.Add(new Vector3(-0.5f, 0, -0.5f)); points.Add(new Vector3(0.5f, 0, -0.5f)); points.Add(new Vector3(0.5f, 0, -0.5f)); points.Add(new Vector3(0.5f, 0, 0.5f)); points.Add(new Vector3(0.5f, 0, 0.5f)); points.Add(new Vector3(-0.5f, 0, 0.5f)); points.Add(new Vector3(-0.5f, 0, 0.5f)); points.Add(new Vector3(-0.5f, 0, -0.5f)); return points.ToArray(); } private static Vector3[] CreateCubeWire() { float size = 1f; Vector3 A = new Vector3(-size / 2f, -size / 2f, -size / 2f); Vector3 B = new Vector3(size / 2f, -size / 2f, -size / 2f); Vector3 C = new Vector3(-size / 2f, -size / 2f, size / 2f); Vector3 D = new Vector3(size / 2f, -size / 2f, size / 2f); Vector3 p1 = A; Vector3 p2 = B; Vector3 p3 = C; Vector3 p4 = D; Vector3 p5 = -D; Vector3 p6 = -C; Vector3 p7 = -B; Vector3 p8 = -A; List points = new List(); points.Add(p1); points.Add(p2); points.Add(p2); points.Add(p4); points.Add(p4); points.Add(p3); points.Add(p3); points.Add(p1); points.Add(p5); points.Add(p6); points.Add(p6); points.Add(p8); points.Add(p5); points.Add(p7); points.Add(p7); points.Add(p8); points.Add(p1); points.Add(p5); points.Add(p2); points.Add(p6); points.Add(p3); points.Add(p7); points.Add(p4); points.Add(p8); return points.ToArray(); } private static Vector3[] CreateSphereWire(int resolution) { List points = new List(); float step = 360.0f / (float)resolution; for (int i = 0; i < resolution; i++) { points.Add(Quaternion.Euler(0f, 0f, i * step) * new Vector3(0f, 0.5f, 0f)); points.Add(Quaternion.Euler(0f, 0f, (i + 1) * step) * new Vector3(0f, 0.5f, 0f)); } for (int i = 0; i < resolution; i++) { points.Add(Quaternion.Euler(0f, i * step, 0f) * new Vector3(0f, 0f, 0.5f)); points.Add(Quaternion.Euler(0f, (i + 1) * step, 0f) * new Vector3(0f, 0f, 0.5f)); } for (int i = 0; i < resolution; i++) { points.Add(Quaternion.Euler(i * step, 0f, i * step) * new Vector3(0f, 0f, 0.5f)); points.Add(Quaternion.Euler((i + 1) * step, 0f, (i + 1) * step) * new Vector3(0f, 0f, 0.5f)); } return points.ToArray(); } private static Vector3[] CreateCylinderWire(int resolution) { List points = new List(); float step = 360.0f / (float)resolution; for (int i = 0; i < resolution; i++) { points.Add(Quaternion.Euler(0f, i * step, 0f) * new Vector3(0f, 0f, 0.5f) + new Vector3(0f, 1f, 0f)); points.Add(Quaternion.Euler(0f, (i + 1) * step, 0f) * new Vector3(0f, 0f, 0.5f) + new Vector3(0f, 1f, 0f)); } for (int i = 0; i < resolution; i++) { points.Add(Quaternion.Euler(0f, i * step, 0f) * new Vector3(0f, 0f, 0.5f) - new Vector3(0f, 1f, 0f)); points.Add(Quaternion.Euler(0f, (i + 1) * step, 0f) * new Vector3(0f, 0f, 0.5f) - new Vector3(0f, 1f, 0f)); } points.Add(new Vector3(0f, -1f, -0.5f)); points.Add(new Vector3(0f, 1f, -0.5f)); points.Add(new Vector3(0f, -1f, 0.5f)); points.Add(new Vector3(0f, 1f, 0.5f)); points.Add(new Vector3(-0.5f, -1f, 0f)); points.Add(new Vector3(-0.5f, 1f, 0f)); points.Add(new Vector3(0.5f, -1f, 0f)); points.Add(new Vector3(0.5f, 1f, 0)); return points.ToArray(); } private static Vector3[] CreateCapsuleWire(int resolution) { List points = new List(); float step = 360.0f / (float)resolution; for (int i = -resolution / 4 - 1; i <= resolution / 4; i++) { points.Add(Quaternion.Euler(0f, 0f, i * step) * new Vector3(0f, 0.5f, 0f) + new Vector3(0f, 0.5f, 0f)); points.Add(Quaternion.Euler(0f, 0f, (i + 1) * step) * new Vector3(0f, 0.5f, 0f) + new Vector3(0f, 0.5f, 0f)); } for (int i = resolution / 2; i < resolution; i++) { points.Add(Quaternion.Euler(i * step, 0f, i * step) * new Vector3(0f, 0f, 0.5f) + new Vector3(0f, 0.5f, 0f)); points.Add(Quaternion.Euler((i + 1) * step, 0f, (i + 1) * step) * new Vector3(0f, 0f, 0.5f) + new Vector3(0f, 0.5f, 0f)); } for (int i = -resolution / 4 - 1; i <= resolution / 4; i++) { points.Add(Quaternion.Euler(0f, 0f, i * step) * new Vector3(0f, -0.5f, 0f) + new Vector3(0f, -0.5f, 0f)); points.Add(Quaternion.Euler(0f, 0f, (i + 1) * step) * new Vector3(0f, -0.5f, 0f) + new Vector3(0f, -0.5f, 0f)); } for (int i = resolution / 2; i < resolution; i++) { points.Add(Quaternion.Euler(i * step, 0f, i * step) * new Vector3(0f, 0f, -0.5f) + new Vector3(0f, -0.5f, 0f)); points.Add(Quaternion.Euler((i + 1) * step, 0f, (i + 1) * step) * new Vector3(0f, 0f, -0.5f) + new Vector3(0f, -0.5f, 0f)); } points.Add(new Vector3(0f, -0.5f, -0.5f)); points.Add(new Vector3(0f, 0.5f, -0.5f)); points.Add(new Vector3(0f, -0.5f, 0.5f)); points.Add(new Vector3(0f, 0.5f, 0.5f)); points.Add(new Vector3(-0.5f, -0.5f, 0f)); points.Add(new Vector3(-0.5f, 0.5f, 0f)); points.Add(new Vector3(0.5f, -0.5f, 0f)); points.Add(new Vector3(0.5f, 0.5f, 0)); return points.ToArray(); } private static Vector3[] CreateConeWire(int resolution) { List points = new List(); float step = 360.0f / (float)resolution; for (int i = 0; i < resolution; i++) { points.Add(Quaternion.Euler(0f, i * step, 0f) * new Vector3(0f, 0f, 0.5f)); points.Add(Quaternion.Euler(0f, (i + 1) * step, 0f) * new Vector3(0f, 0f, 0.5f)); } points.Add(new Vector3(-0.5f, 0f, 0f)); points.Add(new Vector3(0f, 1f, 0f)); points.Add(new Vector3(0.5f, 0f, 0f)); points.Add(new Vector3(0f, 1f, 0f)); points.Add(new Vector3(0f, 0f, -0.5f)); points.Add(new Vector3(0f, 1f, 0f)); points.Add(new Vector3(0f, 0f, 0.5f)); points.Add(new Vector3(0f, 1f, 0f)); return points.ToArray(); } private static Vector3[] CreatePyramidWire() { List points = new List(); points.Add(new Vector3(-0.5f, 0f, -0.5f)); points.Add(new Vector3(0.5f, 0f, -0.5f)); points.Add(new Vector3(0.5f, 0f, -0.5f)); points.Add(new Vector3(0.5f, 0f, 0.5f)); points.Add(new Vector3(0.5f, 0f, 0.5f)); points.Add(new Vector3(-0.5f, 0f, 0.5f)); points.Add(new Vector3(-0.5f, 0f, 0.5f)); points.Add(new Vector3(-0.5f, 0f, -0.5f)); points.Add(new Vector3(-0.5f, 0f, -0.5f)); points.Add(new Vector3(0f, 1f, 0f)); points.Add(new Vector3(0.5f, 0f, -0.5f)); points.Add(new Vector3(0f, 1f, 0f)); points.Add(new Vector3(-0.5f, 0f, 0.5f)); points.Add(new Vector3(0f, 1f, 0f)); points.Add(new Vector3(0.5f, 0f, 0.5f)); points.Add(new Vector3(0f, 1f, 0f)); return points.ToArray(); } private static Vector3[] CreateBoneWire() { float size = 1f / 7f; List points = new List(); points.Add(new Vector3(0.000f, 0.000f, 0.000f)); points.Add(new Vector3(-size, -size, 0.200f)); points.Add(new Vector3(0.000f, 0.000f, 0.000f)); points.Add(new Vector3(size, -size, 0.200f)); points.Add(new Vector3(0.000f, 0.000f, 0.000f)); points.Add(new Vector3(-size, size, 0.200f)); points.Add(new Vector3(0.000f, 0.000f, 0.000f)); points.Add(new Vector3(size, size, 0.200f)); points.Add(new Vector3(-size, -size, 0.200f)); points.Add(new Vector3(0.000f, 0.000f, 1.000f)); points.Add(new Vector3(size, -size, 0.200f)); points.Add(new Vector3(0.000f, 0.000f, 1.000f)); points.Add(new Vector3(-size, size, 0.200f)); points.Add(new Vector3(0.000f, 0.000f, 1.000f)); points.Add(new Vector3(size, size, 0.200f)); points.Add(new Vector3(0.000f, 0.000f, 1.000f)); points.Add(new Vector3(-size, -size, 0.200f)); points.Add(new Vector3(size, -size, 0.200f)); points.Add(new Vector3(size, -size, 0.200f)); points.Add(new Vector3(size, size, 0.200f)); points.Add(new Vector3(size, size, 0.200f)); points.Add(new Vector3(-size, size, 0.200f)); points.Add(new Vector3(-size, size, 0.200f)); points.Add(new Vector3(-size, -size, 0.200f)); return points.ToArray(); } public static Color Transparent(this Color color, float opacity) { return new Color(color.r, color.g, color.b, Mathf.Clamp(opacity, 0f, 1f)); } public static Color[] GetRainbowColors(int number) { Color[] colors = new Color[number]; for (int i = 0; i < number; i++) { float frequency = 5f / number; colors [i].r = Normalise(Mathf.Sin(frequency * i + 0f) * (127f) + 128f, 0f, 255f, 0f, 1f); colors [i].g = Normalise(Mathf.Sin(frequency * i + 2f) * (127f) + 128f, 0f, 255f, 0f, 1f); colors [i].b = Normalise(Mathf.Sin(frequency * i + 4f) * (127f) + 128f, 0f, 255f, 0f, 1f); colors [i].a = 1f; } return colors; } public static float Normalise(float value, float valueMin, float valueMax, float resultMin, float resultMax) { if (valueMax - valueMin != 0f) { return (value - valueMin) / (valueMax - valueMin) * (resultMax - resultMin) + resultMin; } else { //Not possible to normalise input value. return value; } } } }