예제 #1
0
        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);
            }
        }
예제 #2
0
        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));
        }
예제 #3
0
        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;
                }
            }
        }
예제 #4
0
        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();
            }
        }
예제 #5
0
        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();
        }