private void DragSplineCtrlPoint() { Vector3 position; if (GetPositionOnDragPlane(ScreenPointToRay(MousePosition), out position)) { Vector3 prevPosition = m_dragSpline.GetCtrlPointPosition(m_dragPointIndex, m_dragCtrlPointIndex); Vector3 offset = position - prevPosition; float gridSize = GetGridSize(); if (IsUnitSnapping()) { Quaternion quat = Quaternion.LookRotation(m_dragPlane.normal); Vector3 planeOffset = Quaternion.Inverse(quat) * offset; planeOffset.x = planeOffset.x > 0 ? Mathf.Floor(planeOffset.x / gridSize) * gridSize : Mathf.Ceil(planeOffset.x / gridSize) * gridSize; planeOffset.y = planeOffset.y > 0 ? Mathf.Floor(planeOffset.y / gridSize) * gridSize : Mathf.Ceil(planeOffset.y / gridSize) * gridSize; if (planeOffset.x != 0 || planeOffset.y != 0) { offset = quat * planeOffset; } else { offset = Vector3.zero; } } m_dragSpline.SetCtrlPointPosition(m_dragPointIndex, m_dragCtrlPointIndex, prevPosition + offset); } }
private Quaternion GetDragPointRotation(SplineBase spline, int index, int nextIndex, int ctrlPointIndex) { Vector3 nextCtrlPointPosition = spline.InterpolationMode == 0 ? spline.GetCtrlPointPosition(nextIndex, ctrlPointIndex) : spline.GetPointPosition(nextIndex); Vector3 toNextSplinePoint = index < nextIndex ? nextCtrlPointPosition - spline.GetPointPosition(index) : spline.GetPointPosition(index) - nextCtrlPointPosition; GameObject ctrlPoint = index < nextIndex?spline.GetCtrlPoint(index, 1) : spline.GetCtrlPoint(index, 0); Vector3 v = index < nextIndex ? Vector3.forward : Vector3.back; if (toNextSplinePoint.magnitude > MinMag) { Quaternion rotation; if (ctrlPoint != null) { Quaternion rot = Quaternion.FromToRotation(ctrlPoint.transform.localPosition.normalized, v); rotation = Quaternion.LookRotation(toNextSplinePoint) * rot; } else { rotation = Quaternion.LookRotation(toNextSplinePoint); } return(rotation); } return(spline.GetPointRotation(index)); }
private void DrawSplinePoint(ref SplineEditorEventArgs args, ref SplineEditorEvent evnt, SplineRenderer splineRenderer, SplineBase spline, int j) { int mode = spline.GetPointMode(j); if (mode >= 0 && mode < splineRenderer.ControlPointColors.Length) { Handles.color = splineRenderer.ControlPointColors[mode]; } int controlPointsCount = spline.GetCtrlPointsCount(j); for (int k = 0; k < controlPointsCount; ++k) { int scale = 1; if (!splineRenderer.IsControlPointVisible(j, k)) { scale = 0; } Vector3 ctrlPosition = spline.GetCtrlPointPosition(j, k); SplinePointHandle.Result ctrlPointDragResult = DrawPointHandle(splineRenderer, ctrlPosition, scale, true); if (ctrlPointDragResult == SplinePointHandle.Result.Drag) { if (evnt == SplineEditorEvent.None) { args = new SplineEditorEventArgs(spline, j, k); evnt = SplineEditorEvent.SplineCtrlPointDrag; } } if (ctrlPointDragResult == SplinePointHandle.Result.EndDrag) { if (evnt == SplineEditorEvent.None) { args = new SplineEditorEventArgs(spline, j, k); evnt = SplineEditorEvent.SplineCtrlPointDrop; } } } float dragHandleScale = 1; if (m_draggingDragPointHandle && spline == DragSpline && DragPointIndex == j) { dragHandleScale = 0; } JunctionBase junction = spline.GetJunction(j); if (junction != null && junction != NewJunction) { bool drawSplinePoint = junction == null || spline == junction.GetSpline(0) && j == junction.GetSplinePointIndex(0); if (drawSplinePoint) { dragHandleScale = 1.5f; } else { dragHandleScale = 0; } } Handles.color = splineRenderer.SplinePointColor; Vector3 position = spline.GetPointPosition(j); SplinePointHandle.Result dragResult = DrawDragHandle(splineRenderer, position, dragHandleScale, DragSpline == null); if (dragResult == SplinePointHandle.Result.Drag) { if (evnt == SplineEditorEvent.None) { args = new SplineEditorEventArgs(spline, j); evnt = SplineEditorEvent.SplinePointDrag; } } else if (dragResult == SplinePointHandle.Result.EndDrag) { if (evnt == SplineEditorEvent.None) { args = new SplineEditorEventArgs(spline, j); evnt = SplineEditorEvent.SplinePointDrop; } } else if (dragResult == SplinePointHandle.Result.PointerOver) { m_pointerOverSpline = spline; m_pointerOverSplinePointIndex = j; m_pointerOver = true; } if (junction != null && junction != NewJunction) { Handles.color = splineRenderer.JunctionColor; JunctionHandle.Result junctionResult = DrawJunctionHandle(splineRenderer, junction.transform.position, 1); if (junctionResult == JunctionHandle.Result.Click) { evnt = SplineEditorEvent.JunctionClick; args = new SplineEditorEventArgs(junction); } else if (junctionResult == JunctionHandle.Result.Drag) { evnt = SplineEditorEvent.JunctionDrag; args = new SplineEditorEventArgs(junction); } } Handles.color = splineRenderer.SplinePointColor; SplinePointHandle.Result result = DrawPointHandle(splineRenderer, position, 1, false); if (result == SplinePointHandle.Result.EndDrag) { m_draggingDragPointHandle = false; if (evnt == SplineEditorEvent.None) { args = new SplineEditorEventArgs(spline, j); evnt = SplineEditorEvent.SplinePointCreatorDrop; } } else if (result == SplinePointHandle.Result.Drag) { m_draggingDragPointHandle = true; if (evnt == SplineEditorEvent.None) { args = new SplineEditorEventArgs(spline, j); evnt = SplineEditorEvent.SplinePointCreatorDrag; } } }
public virtual void SceneGUI() { if (m_refSpline != null) { if (m_refSplinePosition != m_refSpline.transform.position || m_refSplineRotation != m_refSpline.transform.rotation || m_refSplineScale != m_refSpline.transform.localScale) { m_refSpline.UpdateJunctions(); m_refSplinePosition = m_refSpline.transform.position; m_refSplineRotation = m_refSpline.transform.rotation; m_refSplineScale = m_refSpline.transform.localScale; } } SplineEditorEventArgs eventArgs; SplineEditorEvent eventType = GetEvent(out eventArgs); if (m_splinePointCreatorDrag || m_splinePointDrag || m_beforeSplinePointCreatorDrag || m_beforeJunctionDrag || m_junctionDrag || m_splineCtrlPointDrag) { if (IsMouseUp()) { EndDrag(); } } if (IsSnapToGrid()) { SnapToGrid(); } switch (eventType) { case SplineEditorEvent.SplineCtrlPointDrag: { m_dragSpline = eventArgs.Spline; m_dragPointIndex = eventArgs.PointIndex; m_dragCtrlPointIndex = eventArgs.CtrlPointIndex; GetDragPlane(m_dragSpline.GetCtrlPointPosition(m_dragPointIndex, m_dragCtrlPointIndex)); if (GetPositionOnDragPlane(ScreenPointToRay(MousePosition), out m_beginDragPosition)) { GameObject ctrlPoint = m_dragSpline.GetCtrlPoint(m_dragPointIndex, m_dragCtrlPointIndex); GameObject splinePoint = m_dragSpline.GetPoint(m_dragPointIndex); if (ctrlPoint != null) { RecordObject(ctrlPoint.transform, "BH.S3.DragSplinePoint"); } if (splinePoint != null) { RecordObject(splinePoint.transform, "BH.S3.DragSplinePoint"); } m_splineCtrlPointDrag = true; } else { m_dragSpline = null; m_dragPointIndex = -1; m_dragCtrlPointIndex = -1; } } break; case SplineEditorEvent.SplineCtrlPointDrop: { if (m_splineCtrlPointDrag) { EndDrag(); } else { if (eventArgs.CtrlPointIndex >= 0) { GameObject splinePoint = eventArgs.Spline.GetCtrlPoint(eventArgs.PointIndex, eventArgs.CtrlPointIndex); Select(splinePoint); } else { GameObject splinePoint = eventArgs.Spline.GetPoint(eventArgs.PointIndex); Select(splinePoint); } } } break; case SplineEditorEvent.SplinePointCreatorDrag: { if (!m_beforeSplinePointCreatorDrag && !m_splinePointCreatorDrag) { m_dragSpline = eventArgs.Spline; m_dragPointIndex = eventArgs.PointIndex; GetDragPlane(m_dragSpline.GetPointPosition(m_dragPointIndex)); if (GetPositionOnDragPlane(ScreenPointToRay(MousePosition), out m_beginDragPosition)) { m_beforeSplinePointCreatorDrag = true; } else { m_dragSpline = null; m_dragPointIndex = -1; } } } break; case SplineEditorEvent.SplinePointCreatorDrop: { if (m_splinePointCreatorDrag) { SplineBase dropSpline = eventArgs.Spline; int dropPointIndex = eventArgs.PointIndex; if (m_dragPointIndex >= 0 && m_dragSpline != null && dropPointIndex >= 0 && dropSpline != null && (dropSpline != m_dragSpline || dropPointIndex != m_dragPointIndex)) { dropSpline.Connect(dropPointIndex, m_dragSpline, m_dragPointIndex); JunctionBase junction = dropSpline.GetJunction(dropPointIndex); if (junction.ConnectionsCount == 2) { RegisterCreatedObjectUndo(junction.gameObject, "BH.S3.Junction"); } } Select(m_dragSpline.gameObject); EndDrag(); } else { if (eventArgs.CtrlPointIndex >= 0) { GameObject splinePoint = eventArgs.Spline.GetCtrlPoint(eventArgs.PointIndex, eventArgs.CtrlPointIndex); Select(splinePoint); } else { GameObject splinePoint = eventArgs.Spline.GetPoint(eventArgs.PointIndex); Select(splinePoint); } } } break; case SplineEditorEvent.SplinePointDrag: { if (!m_splinePointDrag) { m_dragSpline = eventArgs.Spline; m_dragPointIndex = eventArgs.PointIndex; GetDragPlane(m_dragSpline.GetPointPosition(m_dragPointIndex)); if (GetPositionOnDragPlane(ScreenPointToRay(MousePosition), out m_beginDragPosition)) { m_splinePointDrag = true; JunctionBase junction = m_dragSpline.GetJunction(m_dragPointIndex); if (junction == null) { GameObject splinePointGO = m_dragSpline.GetPoint(m_dragPointIndex); if (splinePointGO != null) { RegisterFullObjectHierarchyUndo(splinePointGO, "BH.S3.DragSplinePoint"); } } else { int connectionsCount = junction.ConnectionsCount; for (int i = 0; i < connectionsCount; ++i) { SplineBase spline = junction.GetSpline(i); int pointIndex = junction.GetSplinePointIndex(i); GameObject splinePointGO = spline.GetPoint(pointIndex); if (splinePointGO != null) { RegisterFullObjectHierarchyUndo(splinePointGO, "BH.S3.DragSplinePoint"); } } RecordObject(junction.transform, "BH.S3.DragSplinePoint"); } } else { m_dragSpline = null; m_dragPointIndex = -1; } } } break; case SplineEditorEvent.SplinePointDrop: { if (m_splinePointDrag) { SplineBase dropSpline = eventArgs.Spline; int dropPointIndex = eventArgs.PointIndex; if (m_dragPointIndex >= 0 && m_dragSpline != null && dropPointIndex >= 0 && dropSpline != null && (dropSpline != m_dragSpline || dropPointIndex != m_dragPointIndex)) { JunctionBase dropJunction = dropSpline.GetJunction(dropPointIndex); JunctionBase dragJunction = m_dragSpline.GetJunction(m_dragPointIndex); if (dragJunction != dropJunction || dragJunction == null && dropJunction == null) { if (dropJunction != null) { RecordObject(dropJunction, "BH.S3.EndDragSplinePoint"); GameObject splinePointGO = m_dragSpline.GetPoint(m_dragPointIndex); if (splinePointGO != null) { SplinePointBase splinePoint = splinePointGO.GetComponent <SplinePointBase>(); if (splinePoint != null) { RecordObject(splinePoint, "BH.S3.EndDragSplinePoint"); } } } if (dragJunction != null) { RecordObject(dragJunction, "BH.S3.EndDragSplinePoint"); GameObject splinePointGO = dropSpline.GetPoint(dropPointIndex); if (splinePointGO != null) { SplinePointBase splinePoint = splinePointGO.GetComponent <SplinePointBase>(); if (splinePoint != null) { RegisterFullObjectHierarchyUndo(splinePointGO, "BH.S3.EndDragSplinePoint"); } } } dropSpline.Connect(dropPointIndex, m_dragSpline, m_dragPointIndex); if (dragJunction != null && dropJunction != null) { DestroyObject(dragJunction.gameObject); } if (dropJunction == null) { dropJunction = dropSpline.GetJunction(dropPointIndex); if (dropJunction.ConnectionsCount == 2) { RegisterCreatedObjectUndo(dropJunction.gameObject, "BH.S3.EndDragSplinePoint"); } } } } } else { GameObject splinePoint = eventArgs.Spline.GetPoint(eventArgs.PointIndex); Select(splinePoint); } EndDrag(); } break; case SplineEditorEvent.JunctionClick: { Select(eventArgs.Junction.gameObject); } break; case SplineEditorEvent.JunctionDrag: { if (!m_beforeJunctionDrag && !m_junctionDrag) { m_dragJunction = eventArgs.Junction; GetDragPlane(m_dragJunction.transform.position); if (GetPositionOnDragPlane(ScreenPointToRay(MousePosition), out m_beginDragPosition)) { m_beforeJunctionDrag = true; } else { m_dragJunction = null; } } } break; } if (m_beforeSplinePointCreatorDrag) { if (BeginDragSplinePoint()) { m_beforeSplinePointCreatorDrag = false; m_splinePointCreatorDrag = true; } } if (m_splinePointCreatorDrag) { DragSplinePoint(); } if (m_splinePointDrag) { DragSplinePointUsingOffset(); } if (m_splineCtrlPointDrag) { DragSplineCtrlPoint(); } if (m_beforeJunctionDrag) { if (BeginDragJunction()) { m_beforeJunctionDrag = false; m_junctionDrag = true; } } if (m_junctionDrag) { DragSplinePoint(); } }
void IGL.Draw(int cullingMask) { if (m_spline.CurveCount < 1) { return; } m_splineMaterial.SetPass(0); GL.PushMatrix(); GL.MultMatrix(transform.localToWorldMatrix); GL.Begin(GL.LINES); if (IsSelected) { GL.Color(SplineAltColor); for (int i = 0; i < m_spline.PointsCount; ++i) { int ctrlPointsCount = m_spline.GetCtrlPointsCount(i); for (int j = 0; j < ctrlPointsCount; ++j) { if (!IsControlPointVisible(i, j)) { continue; } GL.Vertex(m_spline.transform.InverseTransformPoint(m_spline.GetCtrlPointPosition(i, j))); GL.Vertex(m_spline.GetPointLocalPosition(i)); } } } GL.Color(SplineColor); float step = Mathf.Max(0.01f, Mathf.Min(1, 1 / Smoothness)); for (int i = 0; i < m_spline.CurveCount; ++i) { float t = 0.0f; do { GL.Vertex(m_spline.GetLocalPosition(t, i)); t += step; t = Mathf.Min(1.0f, t); GL.Vertex(m_spline.GetLocalPosition(t, i)); }while (t < 1.0f); if (ShowDirections) { Vector3 dir = m_spline.GetDirection(0.5f, i); Vector3 p = m_spline.GetPosition(0.5f, i); Vector3 dirInCamSpace = Camera.current.transform.InverseTransformDirection(dir).normalized; Vector3 toCamCamSpace = Camera.current.transform.InverseTransformDirection(Camera.current.transform.position - p); if (Mathf.Abs(Vector3.Dot(dirInCamSpace, Vector3.forward)) < 1) { Vector3 perp = Vector3.Cross(dirInCamSpace, toCamCamSpace).normalized; perp = Camera.current.transform.TransformDirection(perp); float scale = GetScreenScale(p, Camera.current) * 0.075f * PointSize; Vector3 p1 = p - dir * scale + perp * 0.5f * scale; Vector3 p2 = p - dir * scale - perp * 0.5f * scale; p = m_spline.transform.InverseTransformPoint(p); p1 = m_spline.transform.InverseTransformPoint(p1); p2 = m_spline.transform.InverseTransformPoint(p2); GL.Vertex(p); GL.Vertex(p1); GL.Vertex(p); GL.Vertex(p2); } } } GL.Color(SplineAltColor); for (int i = 0; i < m_spline.CurveCount; ++i) { float t = 0.0f; do { Vector3 dir = m_spline.GetDirection(t, i); float twist = m_spline.GetTwistAngle(t, i); Quaternion rotation = Quaternion.AngleAxis(twist, dir) * Quaternion.LookRotation(dir, Vector3.up); Vector3 twistVector = m_spline.transform.InverseTransformVector(rotation * Vector3.up); Vector3 p = m_spline.GetPosition(t, i); float scale = GetScreenScale(p, Camera.current) * 0.075f * PointSize; p = m_spline.transform.InverseTransformPoint(p); GL.Vertex(p); GL.Vertex(p + twistVector * scale); t += step; t = Mathf.Min(1.0f, t); }while (t < 1.0f); } GL.End(); GL.PopMatrix(); }