rabidus-test/Assets/Dreamteck/Splines/Editor/SplineEditor/Point Modules/PointModule.cs

345 lines
12 KiB
C#
Raw Permalink Normal View History

2023-07-24 16:38:13 +03:00
namespace Dreamteck.Splines.Editor
{
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.Collections.Generic;
public class PointModule : EditorModule
{
protected bool isClosed
{
get { return editor.GetSplineClosed(); }
}
protected int sampleRate
{
get { return editor.GetSplineSampleRate(); }
}
protected Spline.Type splineType
{
get { return editor.GetSplineType(); }
}
protected Color color {
get { return editor.drawColor; }
}
protected SplineEditor editor;
protected SerializedSplinePoint[] points {
get { return editor.points; }
set { editor.points = value; }
}
protected List<int> selectedPoints
{
get { return editor.selectedPoints; }
set { editor.selectedPoints = value; }
}
public Vector3 center
{
get
{
Vector3 avg = Vector3.zero;
if (points.Length == 0) return avg;
for (int i = 0; i < points.Length; i++) avg += points[i].position;
return avg / points.Length;
}
}
public Vector3 selectionCenter
{
get
{
Vector3 avg = Vector3.zero;
if (selectedPoints.Count == 0) return avg;
for (int i = 0; i < selectedPoints.Count; i++) avg += points[selectedPoints[i]].position;
return avg / selectedPoints.Count;
}
}
protected EditorGUIEvents eventModule;
public delegate void UndoHandler(string title);
public delegate void EmptyHandler();
public delegate void IntHandler(int value);
public delegate void IntArrayHandler(int[] values);
public Spline.Direction duplicationDirection = Spline.Direction.Forward;
public Color highlightColor = Color.white;
public bool showPointNumbers = false;
public event EmptyHandler onBeforeDeleteSelectedPoints;
public event EmptyHandler onSelectionChanged;
public event IntArrayHandler onDuplicatePoint;
private bool movePivot = false;
private Vector3 idealPivot = Vector3.zero;
public PointModule(SplineEditor editor)
{
this.editor = editor;
eventModule = editor.eventModule;
}
protected override void RecordUndo(string title)
{
if (editor.undoHandler != null) editor.undoHandler(title);
}
protected override void Repaint()
{
if (editor.repaintHandler != null) editor.repaintHandler();
}
public override void BeforeSceneDraw(SceneView current)
{
base.BeforeSceneDraw(current);
Event e = Event.current;
if (movePivot)
{
SceneView.lastActiveSceneView.pivot = Vector3.Lerp(SceneView.lastActiveSceneView.pivot, idealPivot, 0.02f);
if (e.type == EventType.MouseDown || e.type == EventType.MouseUp) movePivot = false;
if (Vector3.Distance(SceneView.lastActiveSceneView.pivot, idealPivot) <= 0.05f)
{
SceneView.lastActiveSceneView.pivot = idealPivot;
movePivot = false;
}
}
if (e.type == EventType.KeyDown && e.keyCode == KeyCode.Delete && HasSelection())
{
DeleteSelectedPoints();
e.Use();
}
if(e.type == EventType.ExecuteCommand && Tools.current == Tool.None)
{
switch (e.commandName)
{
case "FrameSelected":
if (points.Length > 0)
{
e.commandName = "";
FramePoints();
e.Use();
}
break;
case "SelectAll":
e.commandName = "";
ClearSelection();
for (int i = 0; i < points.Length; i++)
{
AddPointSelection(i);
}
e.Use();
break;
case "Duplicate":
if (points.Length > 0 && selectedPoints.Count > 0)
{
e.commandName = "";
DuplicateSelected();
e.Use();
}
break;
}
}
}
public virtual void DuplicateSelected()
{
if (selectedPoints.Count == 0) return;
SplinePoint[] newPoints = new SplinePoint[points.Length + selectedPoints.Count];
SplinePoint[] duplicated = new SplinePoint[selectedPoints.Count];
editor.SetPointsCount(newPoints.Length);
int index = 0;
for (int i = 0; i < selectedPoints.Count; i++) duplicated[index++] = points[selectedPoints[i]].CreateSplinePoint();
int min = points.Length - 1, max = 0;
for (int i = 0; i < selectedPoints.Count; i++)
{
if (selectedPoints[i] < min) min = selectedPoints[i];
if (selectedPoints[i] > max) max = selectedPoints[i];
}
int[] selected = selectedPoints.ToArray();
selectedPoints.Clear();
if (duplicationDirection == Spline.Direction.Backward)
{
for (int i = 0; i < min; i++) newPoints[i] = points[i].CreateSplinePoint();
for (int i = 0; i < duplicated.Length; i++)
{
newPoints[i + min] = duplicated[i];
selectedPoints.Add(i + min);
}
for (int i = min; i < points.Length; i++) newPoints[i + duplicated.Length] = points[i].CreateSplinePoint();
}
else
{
for (int i = 0; i <= max; i++) newPoints[i] = points[i].CreateSplinePoint();
for (int i = 0; i < duplicated.Length; i++)
{
newPoints[i + max + 1] = duplicated[i];
selectedPoints.Add(i + max + 1);
}
for (int i = max + 1; i < points.Length; i++) newPoints[i + duplicated.Length] = points[i].CreateSplinePoint();
}
editor.SetPointsArray(newPoints);
RegisterChange();
if (onDuplicatePoint != null) onDuplicatePoint(selected);
}
public virtual void Reset()
{
}
public bool HasSelection()
{
return selectedPoints.Count > 0;
}
public void ClearSelection()
{
selectedPoints.Clear();
Repaint();
if (editor.selectionChangeHandler != null) editor.selectionChangeHandler();
if (onSelectionChanged != null) onSelectionChanged();
}
protected void DeleteSelectedPoints()
{
if (onBeforeDeleteSelectedPoints != null)
{
onBeforeDeleteSelectedPoints();
}
for (int i = 0; i < selectedPoints.Count; i++)
{
DeletePoint(selectedPoints[i]);
for (int n = i; n < selectedPoints.Count; n++)
{
selectedPoints[n]--;
}
}
ClearSelection();
RegisterChange();
editor.ApplyModifiedProperties(true);
}
protected void DeletePoint(int index)
{
editor.DeletePoint(index);
RegisterChange();
}
public void InverseSelection()
{
List<int> inverse = new List<int>();
for (int i = 0; i < (isClosed ? points.Length - 1 : points.Length); i++)
{
bool found = false;
for (int j = 0; j < selectedPoints.Count; j++)
{
if (selectedPoints[j] == i)
{
found = true;
break;
}
}
if (!found) inverse.Add(i);
}
selectedPoints = new List<int>(inverse);
Repaint();
if (editor.selectionChangeHandler != null) editor.selectionChangeHandler();
if (onSelectionChanged != null) onSelectionChanged();
}
protected void SelectPoint(int index)
{
if (selectedPoints.Count == 1 && selectedPoints[0] == index) return;
selectedPoints.Clear();
selectedPoints.Add(index);
Repaint();
if (editor.selectionChangeHandler != null) editor.selectionChangeHandler();
if (onSelectionChanged != null) onSelectionChanged();
}
protected void DeselectPoint(int index)
{
if (selectedPoints.Contains(index))
{
selectedPoints.Remove(index);
Repaint();
if (editor.selectionChangeHandler != null) editor.selectionChangeHandler();
if (onSelectionChanged != null) onSelectionChanged();
}
}
protected void SelectPoints(List<int> indices)
{
selectedPoints.Clear();
for (int i = 0; i < indices.Count; i++)
{
selectedPoints.Add(indices[i]);
}
Repaint();
if (editor.selectionChangeHandler != null) editor.selectionChangeHandler();
if (onSelectionChanged != null) onSelectionChanged();
}
protected void AddPointSelection(int index)
{
if (selectedPoints.Contains(index)) return;
selectedPoints.Add(index);
Repaint();
if (editor.selectionChangeHandler != null) editor.selectionChangeHandler();
if (onSelectionChanged != null) onSelectionChanged();
}
protected void FramePoints()
{
if (points.Length == 0) return;
Vector3 center = Vector3.zero;
Camera camera = SceneView.lastActiveSceneView.camera;
Transform cam = camera.transform;
Vector3 min = Vector3.zero, max = Vector3.zero;
if (HasSelection())
{
for (int i = 0; i < selectedPoints.Count; i++)
{
center += points[selectedPoints[i]].position;
Vector3 local = cam.InverseTransformPoint(points[selectedPoints[i]].position);
if (local.x < min.x) min.x = local.x;
if (local.y < min.y) min.y = local.y;
if (local.z < min.z) min.z = local.z;
if (local.x > max.x) max.x = local.x;
if (local.y > max.y) max.y = local.y;
if (local.z > max.z) max.z = local.z;
}
center /= selectedPoints.Count;
}
else
{
for (int i = 0; i < points.Length; i++)
{
center += points[i].position;
Vector3 local = cam.InverseTransformPoint(points[i].position);
if (local.x < min.x) min.x = local.x;
if (local.y < min.y) min.y = local.y;
if (local.z < min.z) min.z = local.z;
if (local.x > max.x) max.x = local.x;
if (local.y > max.y) max.y = local.y;
if (local.z > max.z) max.z = local.z;
}
center /= points.Length;
}
movePivot = true;
idealPivot = center;
}
}
}