mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2025-09-02 06:19:22 +00:00
Add Popcron.Gizmos license.
Made sure to add the MIT license to their folder.
This commit is contained in:
parent
29060f71c1
commit
7aaec9c512
10 changed files with 21 additions and 0 deletions
445
CVRGizmos/Popcron.Gizmos/GizmosInstance.cs
Normal file
445
CVRGizmos/Popcron.Gizmos/GizmosInstance.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue