182 lines
3.8 KiB
C#
Raw Normal View History

2021-01-03 12:38:02 +00:00
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
namespace Popcron
{
2021-01-04 17:31:58 +00:00
public class GizmosInstance : MonoBehaviour
{
private const int DefaultQueueSize = 4096;
private static GizmosInstance instance;
private static Material defaultMaterial;
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
{
2021-01-05 15:58:12 +00:00
var inst = GetOrCreate();
2021-01-04 17:31:58 +00:00
if (inst.overrideMaterial)
{
return inst.overrideMaterial;
}
return DefaultMaterial;
}
set
{
2021-01-05 15:58:12 +00:00
var inst = GetOrCreate();
2021-01-04 17:31:58 +00:00
inst.overrideMaterial = value;
}
}
2021-01-03 12:38:02 +00:00
2021-01-04 17:31:58 +00:00
/// <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.
2021-01-06 11:52:43 +00:00
var shader = Shader.Find("UI/Default");
2021-01-04 17:31:58 +00:00
defaultMaterial = new Material(shader)
{
hideFlags = HideFlags.HideAndDontSave
};
// Turn on alpha blending
2021-01-06 11:52:43 +00:00
defaultMaterial.SetInt("unity_GUIZTestMode", (int)CompareFunction.Always);
2021-01-04 17:31:58 +00:00
}
return defaultMaterial;
}
}
2021-01-03 12:38:02 +00:00
2021-01-04 17:31:58 +00:00
internal static GizmosInstance GetOrCreate()
{
2021-01-06 11:52:43 +00:00
if (!instance)
2021-01-04 17:31:58 +00:00
{
2021-01-05 15:58:12 +00:00
var gizmosInstances = FindObjectsOfType<GizmosInstance>();
for (var i = 0; i < gizmosInstances.Length; i++)
2021-01-04 17:31:58 +00:00
{
instance = gizmosInstances[i];
//destroy any extra gizmo instances
if (i > 0)
{
2021-01-06 11:52:43 +00:00
Destroy(gizmosInstances[i]);
2021-01-04 17:31:58 +00:00
}
}
//none were found, create a new one
if (!instance)
{
2021-11-07 09:52:03 +00:00
//instance = new GameObject(typeof(GizmosInstance).FullName).AddComponent<GizmosInstance>();
//instance.gameObject.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector;
instance = Locator.GetPlayerCamera().gameObject.AddComponent<GizmosInstance>();
2021-01-05 15:56:14 +00:00
}
2021-01-04 17:31:58 +00:00
}
2021-01-03 12:38:02 +00:00
2021-01-04 17:31:58 +00:00
return instance;
}
2021-01-03 12:38:02 +00:00
2021-01-06 11:52:43 +00:00
private float CurrentTime => Time.time;
2021-01-03 12:38:02 +00:00
2021-01-04 17:31:58 +00:00
/// <summary>
/// Submits an array of points to draw into the queue.
/// </summary>
2021-11-07 09:52:03 +00:00
internal static void Submit(Vector3[] points, Color? color)
2021-01-04 17:31:58 +00:00
{
2021-01-05 15:58:12 +00:00
var inst = GetOrCreate();
2021-01-04 17:31:58 +00:00
//if new frame, reset index
if (inst.lastFrame != Time.frameCount)
{
inst.lastFrame = Time.frameCount;
inst.queueIndex = 0;
}
//excedeed the length, so make it even bigger
if (inst.queueIndex >= inst.queue.Length)
{
2021-01-05 15:58:12 +00:00
var bigger = new Element[inst.queue.Length + DefaultQueueSize];
for (var i = inst.queue.Length; i < bigger.Length; i++)
2021-01-04 17:31:58 +00:00
{
bigger[i] = new Element();
}
Array.Copy(inst.queue, 0, bigger, 0, inst.queue.Length);
inst.queue = bigger;
}
inst.queue[inst.queueIndex].color = color ?? Color.white;
inst.queue[inst.queueIndex].points = points;
inst.queueIndex++;
}
2021-01-03 12:38:02 +00:00
2021-01-04 17:31:58 +00:00
private void OnEnable()
{
//populate queue with empty elements
queue = new Element[DefaultQueueSize];
2021-01-05 15:58:12 +00:00
for (var i = 0; i < DefaultQueueSize; i++)
2021-01-04 17:31:58 +00:00
{
queue[i] = new Element();
}
}
2021-01-03 12:38:02 +00:00
2021-03-07 09:27:23 +00:00
private void Update() =>
2021-01-03 12:38:02 +00:00
//always render something
Gizmos.Line(default, default);
2021-11-07 09:52:03 +00:00
private void OnPostRender()
2021-01-04 17:31:58 +00:00
{
2021-01-06 11:52:43 +00:00
Material.SetPass(0);
2021-01-04 17:31:58 +00:00
2021-01-05 15:58:12 +00:00
var offset = Gizmos.Offset;
2021-01-04 17:31:58 +00:00
GL.PushMatrix();
GL.MultMatrix(Matrix4x4.identity);
GL.Begin(GL.LINES);
2021-01-05 15:58:12 +00:00
var points = new List<Vector3>();
2021-01-04 17:31:58 +00:00
//draw le elements
2021-01-05 15:58:12 +00:00
for (var e = 0; e < queueIndex; e++)
2021-01-04 17:31:58 +00:00
{
//just in case
if (queue.Length <= e)
{
break;
}
2021-01-05 15:58:12 +00:00
var element = queue[e];
2021-01-04 17:31:58 +00:00
points.Clear();
2021-11-07 09:52:03 +00:00
points.AddRange(element.points);
2021-01-04 17:31:58 +00:00
GL.Color(element.color);
2021-01-05 15:58:12 +00:00
for (var i = 0; i < points.Count; i++)
2021-01-04 17:31:58 +00:00
{
GL.Vertex(points[i] + offset);
}
}
GL.End();
GL.PopMatrix();
}
}
2021-01-03 12:38:02 +00:00
}