Add Popcron.Gizmos license.

Made sure to add the MIT license to their folder.
This commit is contained in:
NotAKidoS 2022-09-14 08:34:44 -05:00
parent 29060f71c1
commit 7aaec9c512
10 changed files with 21 additions and 0 deletions

View file

@ -0,0 +1,8 @@
namespace Popcron
{
public class Constants
{
public const string UniqueIdentifier = "Popcron.Gizmos";
public const string EnabledKey = UniqueIdentifier + ".Enabled";
}
}

View file

@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
namespace Popcron
{
public abstract class Drawer
{
private static Dictionary<Type, Drawer> typeToDrawer = null;
public abstract int Draw(ref Vector3[] buffer, params object[] args);
public Drawer()
{
}
public static Drawer Get<T>() where T : class
{
//find all drawers
if (typeToDrawer == null)
{
typeToDrawer = new Dictionary<Type, Drawer>();
//add defaults
typeToDrawer.Add(typeof(CubeDrawer), new CubeDrawer());
typeToDrawer.Add(typeof(LineDrawer), new LineDrawer());
typeToDrawer.Add(typeof(PolygonDrawer), new PolygonDrawer());
typeToDrawer.Add(typeof(SquareDrawer), new SquareDrawer());
//find extras
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in assemblies)
{
Type[] types = assembly.GetTypes();
foreach (Type type in types)
{
if (type.IsAbstract)
{
continue;
}
if (type.IsSubclassOf(typeof(Drawer)) && !typeToDrawer.ContainsKey(type))
{
try
{
Drawer value = (Drawer)Activator.CreateInstance(type);
typeToDrawer[type] = value;
}
catch (Exception e)
{
Debug.LogError($"couldnt register drawer of type {type} because {e.Message}");
}
}
}
}
}
if (typeToDrawer.TryGetValue(typeof(T), out Drawer drawer))
{
return drawer;
}
else
{
return null;
}
}
}
}

View file

@ -0,0 +1,96 @@
using UnityEngine;
namespace Popcron
{
public class CubeDrawer : Drawer
{
public CubeDrawer()
{
}
public override int Draw(ref Vector3[] buffer, params object[] values)
{
Vector3 position = (Vector3)values[0];
Quaternion rotation = (Quaternion)values[1];
Vector3 size = (Vector3)values[2];
size *= 0.5f;
Vector3 point1 = new Vector3(position.x - size.x, position.y - size.y, position.z - size.z);
Vector3 point2 = new Vector3(position.x + size.x, position.y - size.y, position.z - size.z);
Vector3 point3 = new Vector3(position.x + size.x, position.y + size.y, position.z - size.z);
Vector3 point4 = new Vector3(position.x - size.x, position.y + size.y, position.z - size.z);
Vector3 point5 = new Vector3(position.x - size.x, position.y - size.y, position.z + size.z);
Vector3 point6 = new Vector3(position.x + size.x, position.y - size.y, position.z + size.z);
Vector3 point7 = new Vector3(position.x + size.x, position.y + size.y, position.z + size.z);
Vector3 point8 = new Vector3(position.x - size.x, position.y + size.y, position.z + size.z);
point1 = rotation * (point1 - position);
point1 += position;
point2 = rotation * (point2 - position);
point2 += position;
point3 = rotation * (point3 - position);
point3 += position;
point4 = rotation * (point4 - position);
point4 += position;
point5 = rotation * (point5 - position);
point5 += position;
point6 = rotation * (point6 - position);
point6 += position;
point7 = rotation * (point7 - position);
point7 += position;
point8 = rotation * (point8 - position);
point8 += position;
//square
buffer[0] = point1;
buffer[1] = point2;
buffer[2] = point2;
buffer[3] = point3;
buffer[4] = point3;
buffer[5] = point4;
buffer[6] = point4;
buffer[7] = point1;
//other square
buffer[8] = point5;
buffer[9] = point6;
buffer[10] = point6;
buffer[11] = point7;
buffer[12] = point7;
buffer[13] = point8;
buffer[14] = point8;
buffer[15] = point5;
//connectors
buffer[16] = point1;
buffer[17] = point5;
buffer[18] = point2;
buffer[19] = point6;
buffer[20] = point3;
buffer[21] = point7;
buffer[22] = point4;
buffer[23] = point8;
return 24;
}
}
}

View file

@ -0,0 +1,19 @@
using UnityEngine;
namespace Popcron
{
public class LineDrawer : Drawer
{
public LineDrawer()
{
}
public override int Draw(ref Vector3[] buffer, params object[] args)
{
buffer[0] = (Vector3)args[0];
buffer[1] = (Vector3)args[1];
return 2;
}
}
}

View file

@ -0,0 +1,40 @@
using UnityEngine;
namespace Popcron
{
public class PolygonDrawer : Drawer
{
public PolygonDrawer()
{
}
public override int Draw(ref Vector3[] buffer, params object[] values)
{
Vector3 position = (Vector3)values[0];
int points = (int)values[1];
float radius = (float)values[2];
float offset = (float)values[3];
Quaternion rotation = (Quaternion)values[4];
float step = 360f / points;
offset *= Mathf.Deg2Rad;
for (int i = 0; i < points; i++)
{
float cx = Mathf.Cos(Mathf.Deg2Rad * step * i + offset) * radius;
float cy = Mathf.Sin(Mathf.Deg2Rad * step * i + offset) * radius;
Vector3 current = new Vector3(cx, cy);
float nx = Mathf.Cos(Mathf.Deg2Rad * step * (i + 1) + offset) * radius;
float ny = Mathf.Sin(Mathf.Deg2Rad * step * (i + 1) + offset) * radius;
Vector3 next = new Vector3(nx, ny);
buffer[i * 2] = position + (rotation * current);
buffer[(i * 2) + 1] = position + (rotation * next);
}
return points * 2;
}
}
}

View file

@ -0,0 +1,72 @@
using UnityEngine;
namespace Popcron
{
public class SquareDrawer : Drawer
{
public SquareDrawer()
{
}
public override int Draw(ref Vector3[] buffer, params object[] values)
{
Vector2 position = default;
if (values[0] is Vector2 p2)
{
position = p2;
}
else if (values[0] is Vector3 p3)
{
position = p3;
}
Quaternion rotation = (Quaternion)values[1];
Vector2 size = default;
if (values[2] is Vector2 s2)
{
size = s2;
}
else if (values[2] is Vector3 s3)
{
size = s3;
}
size *= 0.5f;
Vector2 point1 = new Vector3(position.x - size.x, position.y - size.y);
Vector2 point2 = new Vector3(position.x + size.x, position.y - size.y);
Vector2 point3 = new Vector3(position.x + size.x, position.y + size.y);
Vector2 point4 = new Vector3(position.x - size.x, position.y + size.y);
point1 = rotation * (point1 - position);
point1 += position;
point2 = rotation * (point2 - position);
point2 += position;
point3 = rotation * (point3 - position);
point3 += position;
point4 = rotation * (point4 - position);
point4 += position;
//square
buffer[0] = point1;
buffer[1] = point2;
buffer[2] = point2;
buffer[3] = point3;
buffer[4] = point3;
buffer[5] = point4;
//loop back to start
buffer[6] = point4;
buffer[7] = point1;
return 8;
}
}
}

View file

@ -0,0 +1,12 @@
using UnityEngine;
namespace Popcron
{
internal class Element
{
public Vector3[] points = { };
public Color color = Color.white;
public bool dashed = false;
public Matrix4x4 matrix = Matrix4x4.identity;
}
}

View file

@ -0,0 +1,394 @@
using System;
using UnityEngine;
namespace Popcron
{
public class Gizmos
{
private static string _prefsKey = null;
private static int? _bufferSize = null;
private static bool? _enabled = null;
private static float? _dashGap = null;
private static bool? _cull = null;
private static int? _pass = null;
private static Vector3? _offset = null;
private static Vector3[] buffer = new Vector3[BufferSize];
/// <summary>
/// By default, it will always render to scene view camera and the main camera.
/// Subscribing to this allows you to whitelist your custom cameras.
/// </summary>
public static Func<Camera, bool> CameraFilter = cam => false;
private static string PrefsKey
{
get
{
if (string.IsNullOrEmpty(_prefsKey))
{
_prefsKey = $"{SystemInfo.deviceUniqueIdentifier}.{Application.companyName}.{Application.productName}.{Constants.UniqueIdentifier}";
}
return _prefsKey;
}
}
/// <summary>
/// The matrix to use.
/// </summary>
public static Matrix4x4 Matrix
{
get => GizmosInstance.Matrix;
set => GizmosInstance.Matrix = value;
}
/// <summary>
/// The matrix to use.
/// </summary>
public static Color Color
{
get => GizmosInstance.Color;
set => GizmosInstance.Color = value;
}
/// <summary>
/// The size of the total gizmos buffer.
/// Default is 4096.
/// </summary>
public static int BufferSize
{
get
{
if (_bufferSize == null)
{
_bufferSize = PlayerPrefs.GetInt($"{PrefsKey}.BufferSize", 4096);
}
return _bufferSize.Value;
}
set
{
value = Mathf.Clamp(value, 0, int.MaxValue);
if (_bufferSize != value)
{
_bufferSize = value;
PlayerPrefs.SetInt($"{PrefsKey}.BufferSize", value);
//buffer size changed, so recreate the buffer array too
buffer = new Vector3[value];
}
}
}
/// <summary>
/// Toggles wether the gizmos could be drawn or not.
/// </summary>
public static bool Enabled
{
get
{
if (_enabled == null)
{
_enabled = PlayerPrefs.GetInt($"{PrefsKey}.Enabled", 1) == 1;
}
return _enabled.Value;
}
set
{
if (_enabled != value)
{
_enabled = value;
PlayerPrefs.SetInt($"{PrefsKey}.Enabled", value ? 1 : 0);
}
}
}
/// <summary>
/// The size of the gap when drawing dashed elements.
/// Default gap size is 0.1
/// </summary>
public static float DashGap
{
get
{
if (_dashGap == null)
{
_dashGap = PlayerPrefs.GetFloat($"{PrefsKey}.DashGap", 0.1f);
}
return _dashGap.Value;
}
set
{
if (_dashGap != value)
{
_dashGap = value;
PlayerPrefs.SetFloat($"{PrefsKey}.DashGap", value);
}
}
}
[Obsolete("This property is obsolete. Use FrustumCulling instead.", false)]
public static bool Cull
{
get
{
return FrustumCulling;
}
set
{
FrustumCulling = value;
}
}
[Obsolete("This property is obsolete. Subscribe to CameraFilter predicate instead and return true for your custom camera.", false)]
public static Camera Camera
{
get => null;
set
{
}
}
/// <summary>
/// Should the camera not draw elements that are not visible?
/// </summary>
public static bool FrustumCulling
{
get
{
if (_cull == null)
{
_cull = PlayerPrefs.GetInt($"{PrefsKey}.FrustumCulling", 1) == 1;
}
return _cull.Value;
}
set
{
if (_cull != value)
{
_cull = value;
PlayerPrefs.SetInt($"{PrefsKey}.FrustumCulling", value ? 1 : 0);
}
}
}
/// <summary>
/// The material being used to render.
/// </summary>
public static Material Material
{
get => GizmosInstance.Material;
set => GizmosInstance.Material = value;
}
/// <summary>
/// Rendering pass to activate.
/// </summary>
public static int Pass
{
get
{
if (_pass == null)
{
_pass = PlayerPrefs.GetInt($"{PrefsKey}.Pass", 0);
}
return _pass.Value;
}
set
{
if (_pass != value)
{
_pass = value;
PlayerPrefs.SetInt($"{PrefsKey}.Pass", value);
}
}
}
/// <summary>
/// Global offset for all points. Default is (0, 0, 0).
/// </summary>
public static Vector3 Offset
{
get
{
const string Delim = ",";
if (_offset == null)
{
string data = PlayerPrefs.GetString($"{PrefsKey}.Offset", 0 + Delim + 0 + Delim + 0);
int indexOf = data.IndexOf(Delim);
int lastIndexOf = data.LastIndexOf(Delim);
if (indexOf + lastIndexOf > 0)
{
string[] arr = data.Split(Delim[0]);
_offset = new Vector3(float.Parse(arr[0]), float.Parse(arr[1]), float.Parse(arr[2]));
}
else
{
return Vector3.zero;
}
}
return _offset.Value;
}
set
{
const string Delim = ",";
if (_offset != value)
{
_offset = value;
PlayerPrefs.SetString($"{PrefsKey}.Offset", value.x + Delim + value.y + Delim + value.y);
}
}
}
/// <summary>
/// Draws an element onto the screen.
/// </summary>
public static void Draw<T>(Color? color, bool dashed, params object[] args) where T : Drawer
{
if (!Enabled)
{
return;
}
Drawer drawer = Drawer.Get<T>();
if (drawer != null)
{
int points = drawer.Draw(ref buffer, args);
//copy from buffer and add to the queue
Vector3[] array = new Vector3[points];
Array.Copy(buffer, array, points);
GizmosInstance.Submit(array, color, dashed);
}
}
/// <summary>
/// Draws an array of lines. Useful for things like paths.
/// </summary>
public static void Lines(Vector3[] lines, Color? color = null, bool dashed = false)
{
if (!Enabled)
{
return;
}
GizmosInstance.Submit(lines, color, dashed);
}
/// <summary>
/// Draw line in world space.
/// </summary>
public static void Line(Vector3 a, Vector3 b, Color? color = null, bool dashed = false)
{
Draw<LineDrawer>(color, dashed, a, b);
}
/// <summary>
/// Draw square in world space.
/// </summary>
public static void Square(Vector2 position, Vector2 size, Color? color = null, bool dashed = false)
{
Square(position, Quaternion.identity, size, color, dashed);
}
/// <summary>
/// Draw square in world space with float diameter parameter.
/// </summary>
public static void Square(Vector2 position, float diameter, Color? color = null, bool dashed = false)
{
Square(position, Quaternion.identity, Vector2.one * diameter, color, dashed);
}
/// <summary>
/// Draw square in world space with a rotation parameter.
/// </summary>
public static void Square(Vector2 position, Quaternion rotation, Vector2 size, Color? color = null, bool dashed = false)
{
Draw<SquareDrawer>(color, dashed, position, rotation, size);
}
/// <summary>
/// Draws a cube in world space.
/// </summary>
public static void Cube(Vector3 position, Quaternion rotation, Vector3 size, Color? color = null, bool dashed = false)
{
Draw<CubeDrawer>(color, dashed, position, rotation, size);
}
/// <summary>
/// Draws a rectangle in screen space.
/// </summary>
public static void Rect(Rect rect, Camera camera, Color? color = null, bool dashed = false)
{
rect.y = Screen.height - rect.y;
Vector2 corner = camera.ScreenToWorldPoint(new Vector2(rect.x, rect.y - rect.height));
Draw<SquareDrawer>(color, dashed, corner + rect.size * 0.5f, Quaternion.identity, rect.size);
}
/// <summary>
/// Draws a representation of a bounding box.
/// </summary>
public static void Bounds(Bounds bounds, Color? color = null, bool dashed = false)
{
Draw<CubeDrawer>(color, dashed, bounds.center, Quaternion.identity, bounds.size);
}
/// <summary>
/// Draws a cone similar to the one that spot lights draw.
/// </summary>
public static void Cone(Vector3 position, Quaternion rotation, float length, float angle, Color? color = null, bool dashed = false, int pointsCount = 16)
{
//draw the end of the cone
float endAngle = Mathf.Tan(angle * 0.5f * Mathf.Deg2Rad) * length;
Vector3 forward = rotation * Vector3.forward;
Vector3 endPosition = position + forward * length;
float offset = 0f;
Draw<PolygonDrawer>(color, dashed, endPosition, pointsCount, endAngle, offset, rotation);
//draw the 4 lines
for (int i = 0; i < 4; i++)
{
float a = i * 90f * Mathf.Deg2Rad;
Vector3 point = rotation * new Vector3(Mathf.Cos(a), Mathf.Sin(a)) * endAngle;
Line(position, position + point + forward * length, color, dashed);
}
}
/// <summary>
/// Draws a sphere at position with specified radius.
/// </summary>
public static void Sphere(Vector3 position, float radius, Color? color = null, bool dashed = false, int pointsCount = 16)
{
float offset = 0f;
Draw<PolygonDrawer>(color, dashed, position, pointsCount, radius, offset, Quaternion.Euler(0f, 0f, 0f));
Draw<PolygonDrawer>(color, dashed, position, pointsCount, radius, offset, Quaternion.Euler(90f, 0f, 0f));
Draw<PolygonDrawer>(color, dashed, position, pointsCount, radius, offset, Quaternion.Euler(0f, 90f, 90f));
}
/// <summary>
/// Draws a circle in world space and billboards towards the camera.
/// </summary>
public static void Circle(Vector3 position, float radius, Camera camera, Color? color = null, bool dashed = false, int pointsCount = 16)
{
float offset = 0f;
Quaternion rotation = Quaternion.LookRotation(position - camera.transform.position);
Draw<PolygonDrawer>(color, dashed, position, pointsCount, radius, offset, rotation);
}
/// <summary>
/// Draws a circle in world space with a specified rotation.
/// </summary>
public static void Circle(Vector3 position, float radius, Quaternion rotation, Color? color = null, bool dashed = false, int pointsCount = 16)
{
float offset = 0f;
Draw<PolygonDrawer>(color, dashed, position, pointsCount, radius, offset, rotation);
}
}
}

View file

@ -0,0 +1,445 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.SceneManagement;
#endif
#if !UNITY_2019_1_OR_NEWER
public struct ScriptableRenderContext { }
public static class RenderPipelineManager
{
public static event Action<ScriptableRenderContext, Camera> endCameraRendering;
}
#endif
namespace Popcron
{
[ExecuteInEditMode]
[AddComponentMenu("")]
public class GizmosInstance : MonoBehaviour
{
private const int DefaultQueueSize = 4096;
private static GizmosInstance instance;
private static bool hotReloaded = true;
private static Material defaultMaterial;
private static Plane[] cameraPlanes = new Plane[6];
private Color color = Color.white;
private Matrix4x4 matrix;
private Material overrideMaterial;
private int queueIndex = 0;
private int lastFrame;
private Element[] queue = new Element[DefaultQueueSize];
/// <summary>
/// The material being used to render
/// </summary>
public static Material Material
{
get
{
GizmosInstance inst = GetOrCreate();
if (inst.overrideMaterial)
{
return inst.overrideMaterial;
}
return DefaultMaterial;
}
set
{
GizmosInstance inst = GetOrCreate();
inst.overrideMaterial = value;
}
}
/// <summary>
/// The matrix to use
/// </summary>
public static Matrix4x4 Matrix
{
get
{
GizmosInstance inst = GetOrCreate();
if (!inst.matrix.isIdentity)
{
return inst.matrix;
}
return Matrix4x4.identity;
}
set
{
GizmosInstance inst = GetOrCreate();
inst.matrix = value;
}
}
/// <summary>
/// The matrix to use
/// </summary>
public static Color Color
{
get
{
GizmosInstance inst = GetOrCreate();
return inst.color;
}
set
{
GizmosInstance inst = GetOrCreate();
inst.color = value;
}
}
/// <summary>
/// The default line renderer material
/// </summary>
public static Material DefaultMaterial
{
get
{
if (!defaultMaterial)
{
// Unity has a built-in shader that is useful for drawing
// simple colored things.
Shader shader = Shader.Find("Hidden/Internal-Colored");
defaultMaterial = new Material(shader)
{
hideFlags = HideFlags.HideAndDontSave
};
// Turn on alpha blending
defaultMaterial.SetInt("_SrcBlend", (int)BlendMode.SrcAlpha);
defaultMaterial.SetInt("_DstBlend", (int)BlendMode.OneMinusSrcAlpha);
defaultMaterial.SetInt("_Cull", (int)CullMode.Off);
defaultMaterial.SetInt("_ZWrite", 0);
}
return defaultMaterial;
}
}
internal static GizmosInstance GetOrCreate()
{
if (hotReloaded || !instance)
{
bool markDirty = false;
GizmosInstance[] gizmosInstances = FindObjectsOfType<GizmosInstance>();
for (int i = 0; i < gizmosInstances.Length; i++)
{
instance = gizmosInstances[i];
//destroy any extra gizmo instances
if (i > 0)
{
if (Application.isPlaying)
{
Destroy(gizmosInstances[i]);
}
else
{
DestroyImmediate(gizmosInstances[i]);
markDirty = true;
}
}
}
//none were found, create a new one
if (!instance)
{
instance = new GameObject(typeof(GizmosInstance).FullName).AddComponent<GizmosInstance>();
instance.gameObject.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector;
markDirty = true;
}
#if UNITY_EDITOR
//mark scene as dirty
if (markDirty && !Application.isPlaying)
{
Scene scene = SceneManager.GetActiveScene();
EditorSceneManager.MarkSceneDirty(scene);
}
#endif
hotReloaded = false;
}
return instance;
}
private float CurrentTime
{
get
{
float time = 0f;
if (Application.isPlaying)
{
time = Time.time;
}
else
{
#if UNITY_EDITOR
time = (float)EditorApplication.timeSinceStartup;
#endif
}
return time;
}
}
/// <summary>
/// Submits an array of points to draw into the queue.
/// </summary>
internal static void Submit(Vector3[] points, Color? color2, bool dashed)
{
GizmosInstance inst = GetOrCreate();
//if new frame, reset index
if (inst.lastFrame != Time.frameCount)
{
inst.lastFrame = Time.frameCount;
inst.queueIndex = 0;
}
//multiply points by matrix
for (int i = 0; i < points.Length; i++)
{
points[i] = inst.matrix.MultiplyPoint3x4(points[i]);
}
//excedeed the length, so make it even bigger
if (inst.queueIndex >= inst.queue.Length)
{
Element[] bigger = new Element[inst.queue.Length + DefaultQueueSize];
for (int i = inst.queue.Length; i < bigger.Length; i++)
{
bigger[i] = new Element();
}
Array.Copy(inst.queue, 0, bigger, 0, inst.queue.Length);
inst.queue = bigger;
}
inst.queue[inst.queueIndex].color = inst.color;
inst.queue[inst.queueIndex].points = points;
inst.queue[inst.queueIndex].dashed = dashed;
inst.queue[inst.queueIndex].matrix = inst.matrix;
inst.queueIndex++;
}
private void OnEnable()
{
//populate queue with empty elements
queue = new Element[DefaultQueueSize];
for (int i = 0; i < DefaultQueueSize; i++)
{
queue[i] = new Element();
}
if (GraphicsSettings.renderPipelineAsset == null)
{
Camera.onPostRender += OnRendered;
}
else
{
RenderPipelineManager.endCameraRendering += OnRendered;
}
}
private void OnDisable()
{
if (GraphicsSettings.renderPipelineAsset == null)
{
Camera.onPostRender -= OnRendered;
}
else
{
RenderPipelineManager.endCameraRendering -= OnRendered;
}
}
private void OnRendered(ScriptableRenderContext context, Camera camera) => OnRendered(camera);
private bool ShouldRenderCamera(Camera camera)
{
if (!camera)
{
return false;
}
//allow the scene and main camera always
bool isSceneCamera = false;
#if UNITY_EDITOR
SceneView sceneView = SceneView.currentDrawingSceneView;
if (sceneView == null)
{
sceneView = SceneView.lastActiveSceneView;
}
if (sceneView != null && sceneView.camera == camera)
{
isSceneCamera = true;
}
#endif
if (isSceneCamera || camera.CompareTag("MainCamera"))
{
return true;
}
if (camera.name.StartsWith("Mirror "))
{
return true;
}
//it passed through the filter
if (Gizmos.CameraFilter?.Invoke(camera) == true)
{
return true;
}
return false;
}
private bool IsVisibleByCamera(Element points, Camera camera)
{
if (!camera)
{
return false;
}
//essentially check if at least 1 point is visible by the camera
for (int i = 0; i < points.points.Length; i++)
{
Vector3 vp = camera.WorldToViewportPoint(points.points[i], camera.stereoActiveEye);
if (vp.x >= 0 && vp.x <= 1 && vp.y >= 0 && vp.y <= 1)
{
return true;
}
}
return false;
}
private void Update()
{
//always render something
Gizmos.Line(default, default);
}
private void OnRendered(Camera camera)
{
Material.SetPass(Gizmos.Pass);
//shouldnt be rendering
if (!Gizmos.Enabled)
{
queueIndex = 0;
}
//check if this camera is ok to render with
if (!ShouldRenderCamera(camera))
{
GL.PushMatrix();
GL.Begin(GL.LINES);
//bla bla bla
GL.End();
GL.PopMatrix();
return;
}
Vector3 offset = Gizmos.Offset;
GL.PushMatrix();
GL.MultMatrix(Matrix4x4.identity);
GL.Begin(GL.LINES);
bool alt = CurrentTime % 1 > 0.5f;
float dashGap = Mathf.Clamp(Gizmos.DashGap, 0.01f, 32f);
bool frustumCull = Gizmos.FrustumCulling;
List<Vector3> points = new List<Vector3>();
//draw le elements
for (int e = 0; e < queueIndex; e++)
{
//just in case
if (queue.Length <= e)
{
break;
}
Element element = queue[e];
//dont render this thingy if its not inside the frustum
if (frustumCull)
{
if (!IsVisibleByCamera(element, camera))
{
continue;
}
}
points.Clear();
if (element.dashed)
{
//subdivide
for (int i = 0; i < element.points.Length - 1; i++)
{
Vector3 pointA = element.points[i];
Vector3 pointB = element.points[i + 1];
Vector3 direction = pointB - pointA;
if (direction.sqrMagnitude > dashGap * dashGap * 2f)
{
float magnitude = direction.magnitude;
int amount = Mathf.RoundToInt(magnitude / dashGap);
direction /= magnitude;
for (int p = 0; p < amount - 1; p++)
{
if (p % 2 == (alt ? 1 : 0))
{
float startLerp = p / (amount - 1f);
float endLerp = (p + 1) / (amount - 1f);
Vector3 start = Vector3.Lerp(pointA, pointB, startLerp);
Vector3 end = Vector3.Lerp(pointA, pointB, endLerp);
points.Add(start);
points.Add(end);
}
}
}
else
{
points.Add(pointA);
points.Add(pointB);
}
}
}
else
{
points.AddRange(element.points);
}
GL.Color(element.color);
for (int i = 0; i < points.Count; i++)
{
GL.Vertex(points[i] + offset);
}
}
GL.End();
GL.PopMatrix();
}
}
}

View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 Phillip DaSilva-Damaskin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.