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; } } }