Beispiel #1
0
 public virtual int Add(Vector2 aPt, PointControl aControls)
 {
     _points.Add(aPt);
     _pointControls.Add(aControls);
     SetDirty();
     return(_points.Count - 1);
 }
Beispiel #2
0
 public PointControl(PointControl aCopy)
 {
     type        = aCopy.type;
     radius      = aCopy.radius;
     controlNext = aCopy.controlNext;
     controlPrev = aCopy.controlPrev;
 }
Beispiel #3
0
 public void Add(Path2D aPath)
 {
     for (int i = 0; i < aPath.Count; i++)
     {
         PointControl p = aPath.GetControls(i);
         Add(aPath[i], new PointControl(p));
     }
 }
Beispiel #4
0
        public ISVGElement Reverse()
        {
            Path2D result = new Path2D();

            EnsureControlsClean();
            for (int i = _points.Count - 1; i >= 0; i -= 1)
            {
                PointControl c = new PointControl(_pointControls[i]);
                c.controlNext = c.controlPrev;
                c.controlPrev = _pointControls[i].controlNext;

                result._points.Add(_points[i]);
                result._pointControls.Add(c);
            }
            result._closed        = _closed;
            result._splitDistance = _splitDistance;

            return(result);
        }
Beispiel #5
0
        public virtual void ReverseSelf()
        {
            List <Vector2>      pts        = new List <Vector2>();
            List <PointControl> ptControls = new List <PointControl>();

            for (int i = _points.Count - 1; i >= 0; i -= 1)
            {
                PointControl c = _pointControls[i];
                c.controlNext = c.controlPrev;
                c.controlPrev = _pointControls[i].controlNext;

                pts.Add(_points[i]);
                ptControls.Add(c);
            }
            _points        = pts;
            _pointControls = ptControls;

            SetDirty();
        }
Beispiel #6
0
        public static void ShowPathLines(Path2D aPathRaw, Matrix4x4 aTransform, bool aShowControls, Path2D.Plane aPlane, PathEditorVisuals aVisuals)
        {
            if (aShowControls)
            {
                Handles.color = aVisuals.colorControlLine;
                for (int i = 0; i < aPathRaw.Count; i++)
                {
                    PointControl c  = aPathRaw.GetControls(i);
                    Vector3      pt = aTransform.MultiplyPoint3x4(Plane(aPathRaw[i], aPlane));

                    if (c.type == PointType.Auto || c.type == PointType.AutoSymmetrical)
                    {
                        Handles.DrawDottedLines(new Vector3[] { pt + aTransform.MultiplyVector(Plane(c.controlPrev, aPlane)), pt, pt, pt + aTransform.MultiplyVector(Plane(c.controlNext, aPlane)) }, 4);
                    }
                    else if (c.type == PointType.Free)
                    {
                        Handles.DrawPolyLine(pt + aTransform.MultiplyVector(Plane(c.controlPrev, aPlane)), pt, pt + aTransform.MultiplyVector(Plane(c.controlNext, aPlane)));
                    }
                    else if (c.type == PointType.Locked)
                    {
                        Handles.DrawPolyLine(pt + aTransform.MultiplyVector(Plane(c.controlPrev, aPlane)), pt + aTransform.MultiplyVector(Plane(-c.controlPrev, aPlane)));
                    }
                    else if (c.type == PointType.CircleCorner)
                    {
                        Vector3 end1 = PathUtil.GetRoundedCornerEnd(i, aPathRaw.GetPathRaw(), aPathRaw.GetControls(), aPathRaw.Closed, c.radius, true);
                        Handles.DrawDottedLine(pt, aTransform.MultiplyPoint(Plane(end1, aPlane)), 4);
                        Vector3 end2 = PathUtil.GetRoundedCornerEnd(i, aPathRaw.GetPathRaw(), aPathRaw.GetControls(), aPathRaw.Closed, c.radius, false);
                        Handles.DrawDottedLine(pt, aTransform.MultiplyPoint(Plane(end2, aPlane)), 4);

                        Vector3 center = Vector2.Lerp(end1.xy() - aPathRaw[i], end2.xy() - aPathRaw[i], 0.5f).normalized *(c.radius + 0.2f);
                        Handles.DrawLine(pt, pt + aTransform.MultiplyVector(Plane(center, aPlane)));
                    }
                }
            }

            Handles.color  = aVisuals.colorLine;
            Handles.matrix = aTransform;
            EditorTools.DrawPolyLine(aPathRaw.GetFinalPath(), aPathRaw.Closed);
            Handles.matrix = Matrix4x4.identity;
        }
Beispiel #7
0
        protected void UpdateControls()
        {
            for (int i = 0; i < _pointControls.Count; i++)
            {
                PointControl p = _pointControls[i];
                if (p.type == PointType.Free)
                {
                }
                else if (p.type == PointType.Locked)
                {
                    p.controlNext = -p.controlPrev;
                }
                else if (p.type == PointType.Sharp)
                {
                    p.controlNext = Vector2.zero;
                    p.controlPrev = Vector2.zero;
                }
                else if (p.type == PointType.CircleCorner)
                {
                    p.controlNext = Vector2.zero;
                    p.controlPrev = Vector2.zero;
                }
                else if (p.type == PointType.AutoSymmetrical)
                {
                    if (!_closed && (i == 0 || i == _pointControls.Count - 1))
                    {
                        p.controlNext = Vector2.zero;
                        p.controlPrev = Vector2.zero;
                    }
                    else
                    {
                        Vector2 n = PathUtil.GetPointNormal(i, _points, _closed);
                        n = new Vector2(-n.y, n.x);

                        float length = (PathUtil.GetSegmentLength(i, _points, _closed) + PathUtil.GetSegmentLength(i - 1, _points, _closed)) / 4;
                        n             = n * length;
                        p.controlNext = n;
                        p.controlPrev = -n;
                    }
                }
                else if (p.type == PointType.Auto)
                {
                    if (!_closed && (i == 0 || i == _pointControls.Count - 1))
                    {
                        p.controlNext = Vector2.zero;
                        p.controlPrev = Vector2.zero;
                    }
                    else
                    {
                        Vector2 n = PathUtil.GetPointNormal(i, _points, _closed);
                        n = new Vector2(-n.y, n.x);

                        float prevLength = PathUtil.GetSegmentLength(i - 1, _points, _closed);
                        float nextLength = PathUtil.GetSegmentLength(i, _points, _closed);
                        p.controlNext = (n * nextLength) / 3;
                        p.controlPrev = -(n * prevLength) / 3;
                    }
                }
            }
            _controlsDirty = false;
        }
Beispiel #8
0
 public virtual void Insert(int aRawIndex, Vector2 aPt, PointControl aControls)
 {
     _points.Insert(aRawIndex, aPt);
     _pointControls.Insert(aRawIndex, aControls);
     SetDirty();
 }
Beispiel #9
0
        public static List <Vector3> GetAllHandleLocations(Matrix4x4 aTransform, Path2D aPathRaw, bool aShowShiftAdd = true, Path2D.Plane aPlane = Path2D.Plane.XY)
        {
            List <Vector3>      result   = new List <Vector3>();
            List <Vector2>      points   = aPathRaw.GetPathRaw();
            List <PointControl> controls = aPathRaw.GetControls();
            bool showControls            = !Event.current.shift && !Event.current.alt;

            // add all points
            List <Vector3> worldPoints = PathUtil.To3D(points, aTransform, aPlane == Path2D.Plane.XY ? PathUtil.ConvertOptions.XY : PathUtil.ConvertOptions.XZ);

            result.AddRange(worldPoints);

            // add the control points
            if (showControls)
            {
                for (int i = 0; i < points.Count; i++)
                {
                    PointControl ctrl = controls[i];
                    PointType    t    = ctrl.type;
                    Vector3      at   = worldPoints[i];

                    if (t == PointType.CircleCorner)
                    {
                        Vector3 end1   = PathUtil.GetRoundedCornerEnd(i, points, controls, aPathRaw.Closed, ctrl.radius, true);
                        Vector3 end2   = PathUtil.GetRoundedCornerEnd(i, points, controls, aPathRaw.Closed, ctrl.radius, false);
                        Vector3 normal = Vector2.Lerp(end1.xy() - points[i], end2.xy() - points[i], 0.5f).normalized;

                        result.Add(at + aTransform.MultiplyVector(Plane(normal * (ctrl.radius + 0.2f), aPlane)));
                    }
                    else if (t == PointType.Free || t == PointType.Locked)
                    {
                        Vector3 v = aTransform.MultiplyVector(Plane(ctrl.controlPrev, aPlane)) + at;
                        result.Add(v);

                        if (t == PointType.Locked)
                        {
                            v = -aTransform.MultiplyVector(Plane(ctrl.controlPrev, aPlane)) + at;
                        }
                        else
                        {
                            v = aTransform.MultiplyVector(Plane(ctrl.controlNext, aPlane)) + at;
                        }
                        result.Add(v);
                    }
                }
            }

            // create the plane on which all edits occur
            Plane editPlane;

            if (aPlane == Path2D.Plane.XY)
            {
                editPlane = new Plane(aTransform.MultiplyPoint3x4(Vector3.zero), aTransform.MultiplyPoint3x4(Vector3.right), aTransform.MultiplyPoint3x4(Vector3.up));
            }
            else
            {
                editPlane = new Plane(aTransform.MultiplyPoint3x4(Vector3.zero), aTransform.MultiplyPoint3x4(Vector3.right), aTransform.MultiplyPoint3x4(Vector3.forward));
            }

            // add shift-add handle
            if (Event.current.shift && aShowShiftAdd)
            {
                Ray   r    = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                float dist = 0;
                if (editPlane.Raycast(r, out dist))
                {
                    result.Add(r.GetPoint(dist));
                }
            }

            return(result);
        }
Beispiel #10
0
        private static void ShowHandles(Path2D aPathRaw, int aIndex, Matrix4x4 aTransform, Matrix4x4 aInvTransform, SerializedProperty aPath, bool aShowMeta, bool aUnlock, Path2D.Plane aPlane, Plane aEditPlane, PathEditorVisuals aVisuals)
        {
            PointControl ctrl   = aPathRaw.GetControls(aIndex);
            bool         locked = ctrl.type == PointType.Locked;
            Vector3      at     = aTransform.MultiplyPoint3x4(Plane(aPathRaw[aIndex], aPlane));

            if (ctrl.type == PointType.Auto || ctrl.type == PointType.AutoSymmetrical || ctrl.type == PointType.Sharp)
            {
            }
            else if (ctrl.type == PointType.CircleCorner)
            {
                if (aPathRaw.Closed || (aIndex != 0 && aIndex != aPathRaw.Count - 1))
                {
                    float size         = HandleUtility.GetHandleSize(at);
                    float radiusOffset = .2f;

                    Vector3 end1   = PathUtil.GetRoundedCornerEnd(aIndex, aPathRaw.GetPathRaw(), aPathRaw.GetControls(), aPathRaw.Closed, ctrl.radius, true);
                    Vector3 end2   = PathUtil.GetRoundedCornerEnd(aIndex, aPathRaw.GetPathRaw(), aPathRaw.GetControls(), aPathRaw.Closed, ctrl.radius, false);
                    Vector3 normal = Vector2.Lerp(end1.xy() - aPathRaw[aIndex], end2.xy() - aPathRaw[aIndex], 0.5f).normalized;

                    Vector3 v  = aTransform.MultiplyVector(Plane(normal * (ctrl.radius + radiusOffset), aPlane)) + at;
                    Vector3 nV = Handles.FreeMoveHandle(v,
                                                        SceneView.lastActiveSceneView.camera.transform.rotation,
                                                        size * aVisuals.sizeControlHandle,
                                                        Vector3.zero,
                                                        aVisuals.capControlHandle);

                    if (nV != v)
                    {
                        SerializedProperty radius = aPath.FindPropertyRelative("_pointControls").GetArrayElementAtIndex(aIndex).FindPropertyRelative("radius");
                        nV  = EditorTools.ProjectPoint(nV, aEditPlane);
                        nV -= at;
                        nV  = aInvTransform.MultiplyVector(nV);
                        Vector2 newPos = Deplane(nV, aPlane);
                        radius.floatValue = SnapScale(radius.floatValue, Mathf.Max(0, newPos.magnitude - radiusOffset), PathSnap.World);
                        _recentInteract   = aIndex;
                        GUI.changed       = true;
                    }

                    if (aShowMeta)
                    {
                        string txt = Math.Round(ctrl.radius, 2).ToString();
                        Handles.Label(v, txt, ShadowStyle);
                        Handles.Label(v, txt, LabelStyle);
                    }
                }
            }
            else
            {
                Vector2 newPos;
                Vector3 v  = aTransform.MultiplyVector(Plane(ctrl.controlPrev, aPlane)) + at;
                Vector3 nV = Handles.FreeMoveHandle(v,
                                                    SceneView.lastActiveSceneView.camera.transform.rotation,
                                                    HandleUtility.GetHandleSize(v) * aVisuals.sizeControlHandle,
                                                    Vector3.zero,
                                                    aVisuals.capControlHandle);

                if (nV != v)
                {
                    SerializedProperty controlProp = aPath.FindPropertyRelative("_pointControls").GetArrayElementAtIndex(aIndex);
                    SerializedProperty type        = controlProp.FindPropertyRelative("type");
                    SerializedProperty prev        = controlProp.FindPropertyRelative("controlPrev");

                    nV                = EditorTools.ProjectPoint(nV, aEditPlane);
                    nV               -= at;
                    nV                = aInvTransform.MultiplyVector(nV);
                    newPos            = Deplane(nV, aPlane);
                    prev.vector2Value = SnapRadial(v, prev.vector2Value, newPos, aTransform, aInvTransform, PathSnap.World);
                    if (aUnlock)
                    {
                        ctrl.type           = PointType.Free;
                        type.enumValueIndex = (int)ctrl.type;
                    }
                    _recentInteract = aIndex;
                    GUI.changed     = true;
                }

                if (ctrl.type == PointType.Locked)
                {
                    v = -aTransform.MultiplyVector(Plane(ctrl.controlPrev, aPlane)) + at;
                }
                else
                {
                    v = aTransform.MultiplyVector(Plane(ctrl.controlNext, aPlane)) + at;
                }

                nV = Handles.FreeMoveHandle(v,
                                            SceneView.lastActiveSceneView.camera.transform.rotation,
                                            HandleUtility.GetHandleSize(v) * aVisuals.sizeControlHandle,
                                            Vector3.zero,
                                            aVisuals.capControlHandle);

                if (nV != v)
                {
                    SerializedProperty controlProp = aPath.FindPropertyRelative("_pointControls").GetArrayElementAtIndex(aIndex);
                    SerializedProperty type        = controlProp.FindPropertyRelative("type");
                    SerializedProperty prev        = controlProp.FindPropertyRelative("controlPrev");
                    SerializedProperty next        = controlProp.FindPropertyRelative("controlNext");

                    nV  = EditorTools.ProjectPoint(nV, aEditPlane);
                    nV -= at;
                    nV  = aInvTransform.MultiplyVector(nV);
                    if (aUnlock)
                    {
                        ctrl.type           = PointType.Free;
                        type.enumValueIndex = (int)ctrl.type;
                    }

                    if (ctrl.type == PointType.Locked)
                    {
                        newPos            = Deplane(-nV, aPlane);
                        prev.vector2Value = SnapRadial(v, prev.vector2Value, newPos, aTransform, aInvTransform, PathSnap.World);
                    }
                    else
                    {
                        newPos            = Deplane(nV, aPlane);
                        next.vector2Value = SnapRadial(v, next.vector2Value, newPos, aTransform, aInvTransform, PathSnap.World);
                    }
                    _recentInteract = aIndex;
                    GUI.changed     = true;
                }

                if (aShowMeta)
                {
                    bool xz = aPlane == Path2D.Plane.XZ;

                    Vector2 prop2   = (locked?ctrl.controlPrev:ctrl.controlNext);
                    Vector3 handle1 = aTransform.MultiplyVector(Plane(ctrl.controlPrev, aPlane)) + at;
                    Vector3 handle2 = (locked?-1:1) * aTransform.MultiplyVector(Plane((locked?ctrl.controlPrev:ctrl.controlNext), aPlane)) + at;
                    float   ang1    = PathUtil.ClockwiseAngle(ctrl.controlPrev, Vector2.right);                //Vector2.Angle(prev.vector2Value, Vector2.right);
                    float   ang2    = PathUtil.ClockwiseAngle((locked?-1:1) * prop2, Vector2.right);           //Vector2.Angle(prop2.vector2Value, Vector2.right);
                    float   mag1    = ctrl.controlPrev.magnitude;
                    float   mag2    = prop2.magnitude;

                    Vector3 pos = Vector3.Lerp(handle1, at, 0.5f);
                    string  txt = Math.Round(mag1, 2).ToString();
                    Handles.Label(pos, txt, ShadowStyle); Handles.Label(pos, txt, LabelStyle);
                    pos = Vector3.Lerp(handle2, at, 0.5f);
                    txt = Math.Round(mag2, 2).ToString();
                    Handles.Label(pos, txt, ShadowStyle); Handles.Label(pos, txt, LabelStyle);

                    pos = handle1;
                    txt = "\u00B0" + Mathf.Round(ang1);
                    Handles.Label(pos, txt, ShadowStyle); Handles.Label(pos, txt, LabelStyle);
                    pos = handle2;
                    txt = "\u00B0" + Mathf.Round(ang2);
                    Handles.Label(pos, txt, ShadowStyle); Handles.Label(pos, txt, LabelStyle);

                    if (ctrl.type == PointType.Free)
                    {
                        if (ang2 < ang1)
                        {
                            ang2 += 360;
                        }
                        float ang     = ang2 - ang1;
                        float halfAng = ang1 + ang / 2;

                        float   arcRadius = HandleUtility.GetHandleSize(at) * aVisuals.sizeVertex * 1.75f;
                        Vector3 centerArc = new Vector3(Mathf.Cos(halfAng * Mathf.Deg2Rad), Mathf.Sin(halfAng * Mathf.Deg2Rad), 0);
                        if (xz)
                        {
                            centerArc = new Vector3(centerArc.x, 0, centerArc.y);
                        }
                        centerArc = aTransform.MultiplyVector(centerArc);

                        var centeredStyle = new GUIStyle(GUI.skin.label);
                        centeredStyle.contentOffset    = new Vector2(-9, -9);
                        centeredStyle.normal.textColor = new Color(0, 0, 0, 0.5f);
                        Handles.Label(at + centerArc * arcRadius * 2f, "\u00B0" + Mathf.Round(ang), centeredStyle);
                        centeredStyle.contentOffset    = new Vector2(-10, -10);
                        centeredStyle.normal.textColor = Color.white;
                        Handles.Label(at + centerArc * arcRadius * 2f, "\u00B0" + Mathf.Round(ang), centeredStyle);

                        Handles.DrawWireArc(at, aPlane == Path2D.Plane.XY?Vector3.forward:Vector3.up, ((xz?handle2:handle1) - at).normalized, ang, arcRadius);
                    }
                }
            }
        }