287 lines
11 KiB
C#
287 lines
11 KiB
C#
|
namespace Dreamteck.Splines.Editor
|
||
|
{
|
||
|
using UnityEngine;
|
||
|
using System.Collections;
|
||
|
using System.Collections.Generic;
|
||
|
using UnityEditor;
|
||
|
|
||
|
public class MainPointModule : PointModule
|
||
|
{
|
||
|
public bool excludeSelected = false;
|
||
|
public int minimumRectSize = 5;
|
||
|
private Vector2 rectStart = Vector2.zero;
|
||
|
private Vector2 rectEnd = Vector2.zero;
|
||
|
private Rect rect;
|
||
|
private bool drag = false;
|
||
|
private bool finalize = false;
|
||
|
private bool pointsMoved = false;
|
||
|
|
||
|
public bool isDragging
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return drag && rect.width >= minimumRectSize && rect.height >= minimumRectSize;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public MainPointModule(SplineEditor editor) : base(editor)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
protected override void OnDrawInspector()
|
||
|
{
|
||
|
string[] options = new string[points.Length + 4];
|
||
|
options[0] = "- - -";
|
||
|
if (selectedPoints.Count > 1) options[0] = "- Multiple -";
|
||
|
options[1] = "All";
|
||
|
options[2] = "None";
|
||
|
options[3] = "Inverse";
|
||
|
for (int i = 0; i < points.Length; i++)
|
||
|
{
|
||
|
options[i + 4] = "Point " + (i + 1);
|
||
|
if (splineType == Spline.Type.Bezier)
|
||
|
{
|
||
|
switch (points[i].type)
|
||
|
{
|
||
|
case SplinePoint.Type.Broken: options[i + 4] += " - Broken"; break;
|
||
|
case SplinePoint.Type.SmoothFree: options[i + 4] += " - Smooth Free"; break;
|
||
|
case SplinePoint.Type.SmoothMirrored: options[i + 4] += " - Smooth Mirrored"; break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
int option = 0;
|
||
|
if (selectedPoints.Count == 1) {
|
||
|
option = selectedPoints[0] + 4;
|
||
|
}
|
||
|
option = EditorGUILayout.Popup("Select", option, options);
|
||
|
switch (option)
|
||
|
{
|
||
|
case 1:
|
||
|
ClearSelection();
|
||
|
for (int i = 0; i < points.Length; i++) AddPointSelection(i);
|
||
|
break;
|
||
|
|
||
|
case 2:
|
||
|
ClearSelection();
|
||
|
break;
|
||
|
|
||
|
case 3:
|
||
|
InverseSelection();
|
||
|
break;
|
||
|
}
|
||
|
if(option >= 4)
|
||
|
{
|
||
|
SelectPoint(option - 4);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected override void OnDrawScene()
|
||
|
{
|
||
|
if (eventModule.v) return;
|
||
|
Transform camTransform = SceneView.currentDrawingSceneView.camera.transform;
|
||
|
if (!drag)
|
||
|
{
|
||
|
if (finalize)
|
||
|
{
|
||
|
if (rect.width > 0f && rect.height > 0f)
|
||
|
{
|
||
|
if (!eventModule.control) ClearSelection();
|
||
|
for (int i = 0; i < points.Length; i++)
|
||
|
{
|
||
|
Vector2 guiPoint = HandleUtility.WorldToGUIPoint(points[i].position);
|
||
|
if (rect.Contains(guiPoint))
|
||
|
{
|
||
|
Vector3 local = camTransform.InverseTransformPoint(points[i].position);
|
||
|
if (local.z >= 0f)
|
||
|
{
|
||
|
AddPointSelection(i);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
finalize = false;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rectEnd = Event.current.mousePosition;
|
||
|
rect = new Rect(Mathf.Min(rectStart.x, rectEnd.x), Mathf.Min(rectStart.y, rectEnd.y), Mathf.Abs(rectEnd.x - rectStart.x), Mathf.Abs(rectEnd.y - rectStart.y));
|
||
|
if (rect.width >= minimumRectSize && rect.height >= minimumRectSize)
|
||
|
{
|
||
|
Color col = highlightColor;
|
||
|
col.a = 0.4f;
|
||
|
Handles.BeginGUI();
|
||
|
EditorGUI.DrawRect(rect, col);
|
||
|
Handles.EndGUI();
|
||
|
SceneView.RepaintAll();
|
||
|
}
|
||
|
}
|
||
|
TextAnchor originalAlignment = GUI.skin.label.alignment;
|
||
|
Color originalColor = GUI.skin.label.normal.textColor;
|
||
|
|
||
|
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
|
||
|
GUI.skin.label.normal.textColor = color;
|
||
|
|
||
|
for (int i = 0; i < points.Length; i++)
|
||
|
{
|
||
|
bool isSelected = selectedPoints.Contains(i);
|
||
|
Vector3 lastPos = points[i].position;
|
||
|
Handles.color = Color.clear;
|
||
|
if (showPointNumbers && camTransform.InverseTransformPoint(points[i].position).z > 0f)
|
||
|
{
|
||
|
if(Event.current.type == EventType.Repaint)
|
||
|
{
|
||
|
Handles.Label(points[i].position + Camera.current.transform.up * HandleUtility.GetHandleSize(points[i].position) * 0.3f, (i + 1).ToString());
|
||
|
}
|
||
|
}
|
||
|
if (!eventModule.alt)
|
||
|
{
|
||
|
if (excludeSelected && isSelected)
|
||
|
{
|
||
|
|
||
|
SplineEditorHandles.FreeMoveRectangle(points[i].position, HandleUtility.GetHandleSize(points[i].position) * 0.1f);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
points[i].SetPosition(SplineEditorHandles.FreeMoveRectangle(points[i].position, HandleUtility.GetHandleSize(points[i].position) * 0.1f));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (lastPos != points[i].position)
|
||
|
{
|
||
|
pointsMoved = true;
|
||
|
if (isSelected)
|
||
|
{
|
||
|
for (int n = 0; n < selectedPoints.Count; n++)
|
||
|
{
|
||
|
if (selectedPoints[n] == i) continue;
|
||
|
points[selectedPoints[n]].SetPosition(points[selectedPoints[n]].position + (points[i].position - lastPos));
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SelectPoint(i);
|
||
|
}
|
||
|
RegisterChange();
|
||
|
}
|
||
|
|
||
|
|
||
|
if (!pointsMoved && !eventModule.alt && editor.eventModule.mouseLeftUp)
|
||
|
{
|
||
|
if(SplineEditorHandles.HoverArea(points[i].position, 0.12f))
|
||
|
{
|
||
|
if (eventModule.control && selectedPoints.Contains(i))
|
||
|
{
|
||
|
DeselectPoint(i);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (eventModule.shift) ShiftSelect(i, points.Length);
|
||
|
else if (eventModule.control) AddPointSelection(i);
|
||
|
else SelectPoint(i);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (!excludeSelected || !isSelected)
|
||
|
{
|
||
|
Handles.color = color;
|
||
|
if (isSelected)
|
||
|
{
|
||
|
Handles.color = highlightColor;
|
||
|
if(Event.current.type == EventType.Repaint)
|
||
|
Handles.DrawWireDisc(points[i].position, -SceneView.currentDrawingSceneView.camera.transform.forward, HandleUtility.GetHandleSize(points[i].position) * 0.14f);
|
||
|
} else Handles.color = color;
|
||
|
if (Event.current.type == EventType.Repaint)
|
||
|
Handles.DrawSolidDisc(points[i].position, -SceneView.currentDrawingSceneView.camera.transform.forward, HandleUtility.GetHandleSize(points[i].position) * 0.09f);
|
||
|
Handles.color = Color.white;
|
||
|
}
|
||
|
}
|
||
|
GUI.skin.label.alignment = originalAlignment;
|
||
|
GUI.skin.label.normal.textColor = originalColor;
|
||
|
|
||
|
if (splineType == Spline.Type.Bezier)
|
||
|
{
|
||
|
Handles.color = color;
|
||
|
for (int i = 0; i < selectedPoints.Count; i++)
|
||
|
{
|
||
|
if (Event.current.type == EventType.Repaint)
|
||
|
Handles.DrawDottedLine(points[selectedPoints[i]].position, points[selectedPoints[i]].tangent, 4f);
|
||
|
if (Event.current.type == EventType.Repaint)
|
||
|
Handles.DrawDottedLine(points[selectedPoints[i]].position, points[selectedPoints[i]].tangent2, 4f);
|
||
|
Vector3 lastPos = points[selectedPoints[i]].tangent;
|
||
|
Vector3 newPos = SplineEditorHandles.FreeMoveCircle(points[selectedPoints[i]].tangent, HandleUtility.GetHandleSize(points[selectedPoints[i]].tangent) * 0.1f);
|
||
|
if (lastPos != newPos)
|
||
|
{
|
||
|
points[selectedPoints[i]].SetTangentPosition(newPos);
|
||
|
RegisterChange();
|
||
|
}
|
||
|
lastPos = points[selectedPoints[i]].tangent2;
|
||
|
newPos = SplineEditorHandles.FreeMoveCircle(points[selectedPoints[i]].tangent2, HandleUtility.GetHandleSize(points[selectedPoints[i]].tangent2) * 0.1f);
|
||
|
if (lastPos != newPos)
|
||
|
{
|
||
|
points[selectedPoints[i]].SetTangent2Position(newPos);
|
||
|
RegisterChange();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (isDragging)
|
||
|
{
|
||
|
if (eventModule.alt || !SceneView.currentDrawingSceneView.camera.pixelRect.Contains(Event.current.mousePosition) || !eventModule.mouseLeft) FinishDrag();
|
||
|
}
|
||
|
|
||
|
if (eventModule.mouseLeftUp)
|
||
|
{
|
||
|
pointsMoved = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ShiftSelect(int index, int pointCount)
|
||
|
{
|
||
|
if (selectedPoints.Count == 0)
|
||
|
{
|
||
|
AddPointSelection(index);
|
||
|
return;
|
||
|
}
|
||
|
int minSelected = pointCount-1, maxSelected = 0;
|
||
|
for (int i = 0; i < selectedPoints.Count; i++)
|
||
|
{
|
||
|
if (minSelected > selectedPoints[i]) minSelected = selectedPoints[i];
|
||
|
if (maxSelected < selectedPoints[i]) maxSelected = selectedPoints[i];
|
||
|
}
|
||
|
|
||
|
if(index > maxSelected)
|
||
|
{
|
||
|
for (int i = maxSelected + 1; i <= index; i++) AddPointSelection(i);
|
||
|
} else if(index < minSelected)
|
||
|
{
|
||
|
for (int i = minSelected-1; i >= index; i--) AddPointSelection(i);
|
||
|
} else
|
||
|
{
|
||
|
for (int i = minSelected + 1; i <= index; i++) AddPointSelection(i);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void StartDrag(Vector2 position)
|
||
|
{
|
||
|
rectStart = position;
|
||
|
drag = true;
|
||
|
finalize = false;
|
||
|
}
|
||
|
|
||
|
public void FinishDrag()
|
||
|
{
|
||
|
if (!drag) return;
|
||
|
drag = false;
|
||
|
finalize = true;
|
||
|
}
|
||
|
|
||
|
public void CancelDrag()
|
||
|
{
|
||
|
drag = false;
|
||
|
finalize = false;
|
||
|
}
|
||
|
}
|
||
|
}
|