rabidus-test/Assets/Dreamteck/Splines/Editor/DSSplineDrawer.cs

164 lines
6.1 KiB
C#

namespace Dreamteck.Splines.Editor
{
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEditor.SceneManagement;
[InitializeOnLoad]
public static class DSSplineDrawer
{
private static bool refreshComputers = false;
private static List<SplineComputer> drawComputers = new List<SplineComputer>();
private static Vector3[] positions = new Vector3[0];
private static UnityEngine.SceneManagement.Scene currentScene;
static DSSplineDrawer()
{
#if UNITY_2019_1_OR_NEWER
SceneView.duringSceneGui += AutoDrawComputers;
#else
SceneView.onSceneGUIDelegate += AutoDrawComputers;
#endif
FindComputers();
EditorApplication.hierarchyChanged += HerarchyWindowChanged;
EditorApplication.playModeStateChanged += ModeChanged;
}
static void ModeChanged(PlayModeStateChange stateChange)
{
refreshComputers = true;
}
private static void HerarchyWindowChanged()
{
if (currentScene != EditorSceneManager.GetActiveScene())
{
currentScene = EditorSceneManager.GetActiveScene();
FindComputers();
}
}
private static void FindComputers()
{
drawComputers.Clear();
SplineComputer[] computers = GameObject.FindObjectsOfType<SplineComputer>();
drawComputers.AddRange(computers);
}
private static void AutoDrawComputers(SceneView current)
{
if (refreshComputers)
{
refreshComputers = false;
FindComputers();
}
for (int i = 0; i < drawComputers.Count; i++)
{
if (!drawComputers[i].editorAlwaysDraw)
{
drawComputers.RemoveAt(i);
i--;
continue;
}
DrawSplineComputer(drawComputers[i]);
}
}
public static void RegisterComputer(SplineComputer comp)
{
if (drawComputers.Contains(comp)) return;
comp.editorAlwaysDraw = true;
drawComputers.Add(comp);
}
public static void UnregisterComputer(SplineComputer comp)
{
for(int i = 0; i < drawComputers.Count; i++)
{
if(drawComputers[i] == comp)
{
drawComputers[i].editorAlwaysDraw = false;
drawComputers.RemoveAt(i);
return;
}
}
}
public static void DrawSplineComputer(SplineComputer comp, double fromPercent = 0.0, double toPercent = 1.0, float alpha = 1f)
{
if (comp == null) return;
if (comp.pointCount < 2) return;
if (Event.current.type != EventType.Repaint) return;
Color prevColor = Handles.color;
Color handleColor = comp.editorPathColor;
handleColor.a = alpha;
Handles.color = handleColor;
if (comp.type == Spline.Type.BSpline && comp.pointCount > 1)
{
SplinePoint[] compPoints = comp.GetPoints();
Handles.color = new Color(handleColor.r, handleColor.g, handleColor.b, 0.5f * alpha);
for (int i = 0; i < compPoints.Length - 1; i++)
{
Handles.DrawLine(compPoints[i].position, compPoints[i + 1].position);
}
Handles.color = handleColor;
}
if (!comp.editorDrawThickness)
{
if (positions.Length != comp.sampleCount * 2)
{
positions = new Vector3[comp.sampleCount * 2];
}
Vector3 prevPoint = comp.EvaluatePosition(fromPercent);
int pointIndex = 0;
for (int i = 1; i < comp.sampleCount; i++)
{
positions[pointIndex] = prevPoint;
pointIndex++;
positions[pointIndex] = comp[i].position;
pointIndex++;
prevPoint = positions[pointIndex - 1];
}
Handles.DrawLines(positions);
}
else
{
Transform editorCamera = SceneView.currentDrawingSceneView.camera.transform;
if (positions.Length != comp.sampleCount * 6) positions = new Vector3[comp.sampleCount * 6];
SplineSample prevResult = comp.Evaluate(fromPercent);
Vector3 prevNormal = prevResult.up;
if (comp.editorBillboardThickness) prevNormal = (editorCamera.position - prevResult.position).normalized;
Vector3 prevRight = Vector3.Cross(prevResult.forward, prevNormal).normalized * prevResult.size * 0.5f;
int pointIndex = 0;
for (int i = 1; i < comp.sampleCount; i++)
{
Vector3 newNormal = comp[i].up;
if (comp.editorBillboardThickness) newNormal = (editorCamera.position - comp[i].position).normalized;
Vector3 newRight = Vector3.Cross(comp[i].forward, newNormal).normalized * comp[i].size * 0.5f;
positions[pointIndex] = prevResult.position + prevRight;
positions[pointIndex + comp.sampleCount * 2] = prevResult.position - prevRight;
positions[pointIndex + comp.sampleCount * 4] = comp[i].position - newRight;
pointIndex++;
positions[pointIndex] = comp[i].position + newRight;
positions[pointIndex + comp.sampleCount * 2] = comp[i].position - newRight;
positions[pointIndex + comp.sampleCount * 4] = comp[i].position + newRight;
pointIndex++;
prevResult = comp[i];
prevRight = newRight;
prevNormal = newNormal;
}
Handles.DrawLines(positions);
}
Handles.color = prevColor;
}
}
}