Inheritance: MonoBehaviour
 public static void DrawOtherPoints(BezierCurve curve, BezierPoint caller)
 {
     foreach(BezierPoint p in curve.GetAnchorPoints())
     {
         if(p != caller) DrawPointSceneGUI(p);
     }
 }
	void OnEnable(){
		point = (BezierPoint)target;
		
		handleTypeProp = serializedObject.FindProperty("handleStyle");
		handle1Prop = serializedObject.FindProperty("_handle1");
		handle2Prop = serializedObject.FindProperty("_handle2");
	}	
Example #3
0
File: Curve.cs Project: ldh9451/XLE
        public BezierSpline CreateSpline()
        {
            IList<IControlPoint> points = GetChildList<IControlPoint>(Schema.bezierType.pointChild);
            BezierSpline spline = new BezierSpline();
            spline.IsClosed = GetAttribute<bool>(Schema.bezierType.isClosedAttribute);

            BezierPoint bpt = new BezierPoint();
            foreach (var cpt in points)
            {
                bpt.Position = cpt.Translation;
                spline.Add(bpt);
            }
            return spline;
        }
Example #4
0
 public static void DrawCurveMirrored(Transform localTransform, BezierPoint p1, BezierPoint p2, float resolution, Axis axis)
 {
     DrawCurveMirrored(localTransform, p1, p2, GetNumPoints(p1, p2, resolution), axis);
 }
Example #5
0
 public bool RemovePoint(BezierPoint point)
 {
     _dirty = _points.Remove(point);
     return(_dirty);
 }
Example #6
0
	/// <summary>
	/// 	- Approximates the length
	/// </summary>
	/// <returns>
	/// 	- The approximate length
	/// </returns>
	/// <param name='p1'>
	/// 	- The bezier point at the start of the curve
	/// </param>
	/// <param name='p2'>
	/// 	- The bezier point at the end of the curve
	/// </param>
	/// <param name='resolution'>
	/// 	- The number of points along the curve used to create measurable segments
	/// </param>
	public static float ApproximateLength(BezierPoint p1, BezierPoint p2, int resolution = 10)
	{
		float _res = resolution;
		float total = 0;
		Vector3 lastPosition = p1.position;
		Vector3 currentPosition;
		
		for(int i = 0; i < resolution + 1; i++)
		{
			currentPosition = GetPoint(p1, p2, i / _res);
			total += (currentPosition - lastPosition).magnitude;
			lastPosition = currentPosition;
		}
		
		return total;
	}
	private static void HandleConnected(BezierPoint p){
		Handles.color = Color.cyan;
		
		Vector3 newGlobal1 = Handles.FreeMoveHandle(p.globalHandle1, p.transform.rotation, HandleUtility.GetHandleSize(p.globalHandle1)*0.15f, Vector3.zero, Handles.SphereCap);
		
		if(newGlobal1 != p.globalHandle1){
			Undo.RecordObject(p, "Move Handle");
			p.globalHandle1 = newGlobal1;
			p.globalHandle2 = -(newGlobal1 - p.position) + p.position;
		}
		
		Vector3 newGlobal2 = Handles.FreeMoveHandle(p.globalHandle2, p.transform.rotation, HandleUtility.GetHandleSize(p.globalHandle2)*0.15f, Vector3.zero, Handles.SphereCap);
		
		if(newGlobal2 != p.globalHandle2){
			Undo.RecordObject(p, "Move Handle");
			p.globalHandle1 = -(newGlobal2 - p.position) + p.position;
			p.globalHandle2 = newGlobal2;
		}
	}
Example #8
0
	/// <summary>
	/// 	- Removes the given point from the curve ("points" array)
	/// </summary>
	/// <param name='point'>
	/// 	- The point to remove
	/// </param>
	public void RemovePoint(BezierPoint point)
	{
		List<BezierPoint> tempArray = new List<BezierPoint>(points);
		tempArray.Remove(point);
		points = tempArray.ToArray();
		dirty = false;
	}
Example #9
0
	/// <summary>
	/// 	- Draws the curve in the Editor
	/// </summary>
	/// <param name='p1'>
	/// 	- The bezier point at the beginning of the curve
	/// </param>
	/// <param name='p2'>
	/// 	- The bezier point at the end of the curve
	/// </param>
	/// <param name='resolution'>
	/// 	- The number of segments along the curve to draw
	/// </param>
	public static void DrawCurve(BezierPoint p1, BezierPoint p2, int resolution)
	{
		int limit = resolution+1;
		float _res = resolution;
		Vector3 lastPoint = p1.position;
		Vector3 currentPoint = Vector3.zero;
		
		for(int i = 1; i < limit; i++){
			currentPoint = GetPoint(p1, p2, i/_res);
			Gizmos.DrawLine(lastPoint, currentPoint);
			lastPoint = currentPoint;
		}		
	}	
Example #10
0
 public HitTestResult(Link link, BezierPoint controlHandle)
 {
     Link          = link;
     ControlHandle = controlHandle;
 }
Example #11
0
    // Helper method for finding a pair of points and a corresponding local 't' for given global 't'
    TBetweenPointsData GetTBetweenPoints(float t)
    {
        if (t <= 0)
        {
            return(new TBetweenPointsData {
                p1 = points[0], p2 = points[1], t = 0
            });
        }
        else if (t >= 1)
        {
            if (close)
            {
                return(new TBetweenPointsData {
                    p1 = points[points.Length - 1], p2 = points[0], t = 1
                });
            }
            else
            {
                return(new TBetweenPointsData {
                    p1 = points[points.Length - 2], p2 = points[points.Length - 1], t = 1
                });
            }
        }
        else
        {
            float totalPercent = 0;
            float curvePercent = 0;

            BezierPoint p1 = null;
            BezierPoint p2 = null;

            int approxResolution = 10;


            int safetyCounter = 0;
            int maxIters      = 10;

            while (p1 == null && p2 == null)
            {
                totalPercent = 0;

                int end = close ? points.Length : points.Length - 1;
                for (int i = 0; i < end; i++)
                {
                    var pa = points[i];
                    var pb = points[(i + 1) % points.Length];
                    curvePercent = ApproximateLength(pa, pb, approxResolution) / length;

                    if ((totalPercent + curvePercent > t) || Mathf.Abs(t - (totalPercent + curvePercent)) < 5e-6)
                    {
                        p1 = pa;
                        p2 = pb;
                        break;
                    }
                    else
                    {
                        totalPercent += curvePercent;
                    }
                }

                approxResolution += 10;

                if (++safetyCounter >= maxIters)
                {
                    Debug.LogError("BezierCurve couldn't find a point", this);
                    return(default(TBetweenPointsData));
                }
            }

            if (p1 == null)
            {
                Debug.LogError("p1 is null");
            }
            if (p2 == null)
            {
                Debug.LogError("p2 is null");
            }

            var ret = new TBetweenPointsData();
            ret.p1 = p1;
            ret.p2 = p2;
            ret.t  = (t - totalPercent) / curvePercent;

            return(ret);
        }
    }
Example #12
0
 /// <summary>
 /// Returns the number of points required to interpolate the given bezier points to a given resolution.
 /// </summary>
 public static int GetNumPoints(BezierPoint p1, BezierPoint p2, float resolution)
 {
     return(GetNumPoints(p1.position, p1.globalHandle2, p2.position, p2.globalHandle1, resolution));
 }
Example #13
0
        public override void OnMouseUp(ExMouseEventArgs e)
        {
            base.OnMouseUp(e);

            PressMouseButton = MouseButtons.None;
            //MouseDownObject = HitTestResult.Empty;

            if (NewLineFrom != null)
            {
                EndNewLineTest(e);
                e.Suppress = true;
            }
            else if (e.Button == MouseButtons.Left && PressedObject.Link != null && Helper.TestModifierKeys(Keys.Shift))
            {
                if (!string.IsNullOrEmpty(PressedObject.Link.Hyperlink))
                {
                    Helper.OpenUrl(PressedObject.Link.Hyperlink);
                }
            }
            else
            {
                if (DragingControlHandle != BezierPoint.None && TempLayout != null && SelectedObject.Link != null)
                {
                    Link line      = SelectedObject.Link;
                    var  oldPoints = line.GetBezierPoints();
                    //Rectangle rect = line.Bounds;

                    Point pt = View.PointToLogic(new Point(e.X, e.Y));
                    Point pts;
                    Topic topic;
                    switch (DragingControlHandle)
                    {
                    case BezierPoint.StartPoint:
                        topic = View.GetTopicAt(e.X, e.Y);
                        if (line.CanStartFrom(topic))
                        {
                            line.From = topic;
                        }
                        break;

                    case BezierPoint.EndPoint:
                        topic = View.GetTopicAt(e.X, e.Y);
                        if (line.CanEndTo(topic))
                        {
                            line.Target = topic;
                        }
                        break;

                    case BezierPoint.ControlPoint1:
                        pts = PaintHelper.CenterPoint(line.LayoutData.StartBounds);
                        //line.LayoutData.CPLength1 = PaintHelper.GetDistance(pts, pt);
                        //line.LayoutData.CPAngle1 = PaintHelper.GetAngle(pts, pt);
                        line.LayoutData.CP1 = new BezierControlPoint(PaintHelper.GetAngle(pts, pt), PaintHelper.GetDistance(pts, pt));
                        break;

                    case BezierPoint.ControlPoint2:
                        pts = PaintHelper.CenterPoint(line.LayoutData.EndBounds);
                        //line.LayoutData.CPLength2 = PaintHelper.GetDistance(pts, pt);
                        //line.LayoutData.CPAngle2 = PaintHelper.GetAngle(pts, pt);
                        line.LayoutData.CP2 = new BezierControlPoint(PaintHelper.GetAngle(pts, pt), PaintHelper.GetDistance(pts, pt));
                        break;
                    }

                    line.RefreshLayout();
                    line.SetChanged();
                    TempLayout = line.LayoutData.Clone();

                    InvalidateLink(oldPoints, line.Width, true);
                    InvalidateLink(line, false);
                    //InvalidateLinkRegion(oldPoints, line.GetBezierPoints(), line.LineWidth);

                    /*if (rect.IsEmpty)
                     *  rect = line.Bounds;
                     * else
                     *  rect = Rectangle.Union(rect, line.Bounds);
                     * rect.Location = View.PointToReal(rect.Location);
                     * InvalidateChart(rect, true);*/
                }

                DragingControlHandle = BezierPoint.None;
            }
        }
Example #14
0
    public static float ApproximateLength(BezierPoint p1, BezierPoint p2, float resolution = 0.5f)
    {
        int numPoints = GetNumPoints(p1, p2, resolution);

        return(ApproximateLength(p1, p2, numPoints));
    }
Example #15
0
 /// <summary>
 ///     - Approximates the length
 /// </summary>
 /// <returns>
 ///     - The approximate length
 /// </returns>
 /// <param name='p1'>
 ///     - The bezier point at the start of the curve
 /// </param>
 /// <param name='p2'>
 ///     - The bezier point at the end of the curve
 /// </param>
 /// <param name='numPoints'>
 ///     - The number of points along the curve used to create measurable segments
 /// </param>
 public static float ApproximateLength(BezierPoint p1, BezierPoint p2, int numPoints = 10)
 {
     return(ApproximateLength(p1.position, p1.globalHandle2, p2.position, p2.globalHandle1, numPoints));
 }
Example #16
0
 public static Vector3 GetPoint(BezierPoint p1, BezierPoint p2, float t)
 {
     return(GetPoint(p1.position, p1.globalHandle2, p2.position, p2.globalHandle1, t));
 }
    static void DrawPointSceneGUI(BezierPoint point)
    {
        Handles.Label(point.position + new Vector3(0, HandleUtility.GetHandleSize(point.position) * 0.4f, 0), point.gameObject.name);

        Handles.color = Color.green;
        Vector3 newPosition = Handles.FreeMoveHandle(point.position, point.transform.rotation, HandleUtility.GetHandleSize(point.position)*0.1f, Vector3.zero, Handles.RectangleCap);

        if(newPosition != point.position)
        {
            Undo.RegisterUndo(point.transform, "Move Point");
            point.transform.position = newPosition;
        }

        if(point.handleStyle != BezierPoint.HandleStyle.None)
        {
            Handles.color = Color.cyan;
            Vector3 newGlobal1 = Handles.FreeMoveHandle(point.globalHandle1, point.transform.rotation, HandleUtility.GetHandleSize(point.globalHandle1)*0.075f, Vector3.zero, Handles.CircleCap);
            if(point.globalHandle1 != newGlobal1)
            {
                Undo.RegisterUndo(point, "Move Handle");
                point.globalHandle1 = newGlobal1;
                if(point.handleStyle == BezierPoint.HandleStyle.Connected) point.globalHandle2 = -(newGlobal1 - point.position) + point.position;
            }

            Vector3 newGlobal2 = Handles.FreeMoveHandle(point.globalHandle2, point.transform.rotation, HandleUtility.GetHandleSize(point.globalHandle2)*0.075f, Vector3.zero, Handles.CircleCap);
            if(point.globalHandle2 != newGlobal2)
            {
                Undo.RegisterUndo(point, "Move Handle");
                point.globalHandle2 = newGlobal2;
                if(point.handleStyle == BezierPoint.HandleStyle.Connected) point.globalHandle1 = -(newGlobal2 - point.position) + point.position;
            }

            Handles.color = Color.yellow;
            Handles.DrawLine(point.position, point.globalHandle1);
            Handles.DrawLine(point.position, point.globalHandle2);
        }
    }
Example #18
0
    void DrawPointInspector(BezierPoint point, int index)
    {
        SerializedObject serObj = new SerializedObject(point);

        SerializedProperty handleStyleProp = serObj.FindProperty("handleStyle");
        SerializedProperty handle1Prop     = serObj.FindProperty("_handle1");
        SerializedProperty handle2Prop     = serObj.FindProperty("_handle2");

        EditorGUILayout.BeginHorizontal();

        if (GUILayout.Button("X", GUILayout.Width(20)))
        {
            //Undo.RegisterUndo("Remove Point");
            pointsProp.MoveArrayElement(curve.GetPointIndex(point), curve.pointCount - 1);
            pointsProp.arraySize--;
            DestroyImmediate(point.gameObject);
            return;
        }

        EditorGUILayout.ObjectField(point.gameObject, typeof(GameObject), true);

        if (index != 0 && GUILayout.Button(@"/\", GUILayout.Width(25)))
        {
            UnityEngine.Object other = pointsProp.GetArrayElementAtIndex(index - 1).objectReferenceValue;
            pointsProp.GetArrayElementAtIndex(index - 1).objectReferenceValue = point;
            pointsProp.GetArrayElementAtIndex(index).objectReferenceValue     = other;
        }

        if (index != pointsProp.arraySize - 1 && GUILayout.Button(@"\/", GUILayout.Width(25)))
        {
            UnityEngine.Object other = pointsProp.GetArrayElementAtIndex(index + 1).objectReferenceValue;
            pointsProp.GetArrayElementAtIndex(index + 1).objectReferenceValue = point;
            pointsProp.GetArrayElementAtIndex(index).objectReferenceValue     = other;
        }

        EditorGUILayout.EndHorizontal();

        EditorGUI.indentLevel++;
        EditorGUI.indentLevel++;

        int newType = (int)((object)EditorGUILayout.EnumPopup("Handle Type", (BezierPoint.HandleStyle)handleStyleProp.enumValueIndex));

        if (newType != handleStyleProp.enumValueIndex)
        {
            handleStyleProp.enumValueIndex = newType;
            if (newType == 0)
            {
                if (handle1Prop.vector3Value != Vector3.zero)
                {
                    handle2Prop.vector3Value = -handle1Prop.vector3Value;
                }
                else if (handle2Prop.vector3Value != Vector3.zero)
                {
                    handle1Prop.vector3Value = -handle2Prop.vector3Value;
                }
                else
                {
                    handle1Prop.vector3Value = new Vector3(0.1f, 0, 0);
                    handle2Prop.vector3Value = new Vector3(-0.1f, 0, 0);
                }
            }

            else if (newType == 1)
            {
                if (handle1Prop.vector3Value == Vector3.zero && handle2Prop.vector3Value == Vector3.zero)
                {
                    handle1Prop.vector3Value = new Vector3(0.1f, 0, 0);
                    handle2Prop.vector3Value = new Vector3(-0.1f, 0, 0);
                }
            }

            else if (newType == 2)
            {
                handle1Prop.vector3Value = Vector3.zero;
                handle2Prop.vector3Value = Vector3.zero;
            }
        }

        Vector3 newPointPos = EditorGUILayout.Vector3Field("Position : ", point.transform.localPosition);

        if (newPointPos != point.transform.localPosition)
        {
            Undo.RecordObject(point.transform, "Move Bezier Point");
            point.transform.localPosition = newPointPos;
        }

        if (handleStyleProp.enumValueIndex == 0)
        {
            Vector3 newPosition;

            newPosition = EditorGUILayout.Vector3Field("Handle 1", handle1Prop.vector3Value);
            if (newPosition != handle1Prop.vector3Value)
            {
                handle1Prop.vector3Value = newPosition;
                handle2Prop.vector3Value = -newPosition;
            }

            newPosition = EditorGUILayout.Vector3Field("Handle 2", handle2Prop.vector3Value);
            if (newPosition != handle2Prop.vector3Value)
            {
                handle1Prop.vector3Value = -newPosition;
                handle2Prop.vector3Value = newPosition;
            }
        }

        else if (handleStyleProp.enumValueIndex == 1)
        {
            EditorGUILayout.PropertyField(handle1Prop);
            EditorGUILayout.PropertyField(handle2Prop);
        }

        EditorGUI.indentLevel--;
        EditorGUI.indentLevel--;

        if (GUI.changed)
        {
            serObj.ApplyModifiedProperties();
            EditorUtility.SetDirty(serObj.targetObject);
        }
    }
    void DrawPointInspector(BezierPoint point, int index)
    {
        SerializedObject serObj = new SerializedObject(point);

        SerializedProperty handleStyleProp = serObj.FindProperty("handleStyle");
        SerializedProperty handle1Prop = serObj.FindProperty("_handle1");
        SerializedProperty handle2Prop = serObj.FindProperty("_handle2");

        EditorGUILayout.BeginHorizontal();

        if(GUILayout.Button("X", GUILayout.Width(20)))
        {
            Undo.RegisterSceneUndo("Remove Point");
            pointsProp.MoveArrayElement(curve.GetPointIndex(point), curve.pointCount - 1);
            pointsProp.arraySize--;
            DestroyImmediate(point.gameObject);
            return;
        }

        EditorGUILayout.ObjectField(point.gameObject, typeof(GameObject), true);

        if(index != 0 && GUILayout.Button(@"/\", GUILayout.Width(25)))
        {
            UnityEngine.Object other = pointsProp.GetArrayElementAtIndex(index - 1).objectReferenceValue;
            pointsProp.GetArrayElementAtIndex(index - 1).objectReferenceValue = point;
            pointsProp.GetArrayElementAtIndex(index).objectReferenceValue = other;
        }

        if(index != pointsProp.arraySize - 1 && GUILayout.Button(@"\/", GUILayout.Width(25)))
        {
            UnityEngine.Object other = pointsProp.GetArrayElementAtIndex(index + 1).objectReferenceValue;
            pointsProp.GetArrayElementAtIndex(index + 1).objectReferenceValue = point;
            pointsProp.GetArrayElementAtIndex(index).objectReferenceValue = other;
        }

        EditorGUILayout.EndHorizontal();

        EditorGUI.indentLevel++;
        EditorGUI.indentLevel++;

        int newType = (int)((object)EditorGUILayout.EnumPopup("Handle Type", (BezierPoint.HandleStyle)handleStyleProp.enumValueIndex));

        if(newType != handleStyleProp.enumValueIndex)
        {
            handleStyleProp.enumValueIndex = newType;
            if(newType == 0)
            {
                if(handle1Prop.vector3Value != Vector3.zero) handle2Prop.vector3Value = -handle1Prop.vector3Value;
                else if(handle2Prop.vector3Value != Vector3.zero) handle1Prop.vector3Value = -handle2Prop.vector3Value;
                else
                {
                    handle1Prop.vector3Value = new Vector3(0.1f, 0, 0);
                    handle2Prop.vector3Value = new Vector3(-0.1f, 0, 0);
                }
            }

            else if(newType == 1)
            {
                if(handle1Prop.vector3Value == Vector3.zero && handle2Prop.vector3Value == Vector3.zero)
                {
                    handle1Prop.vector3Value = new Vector3(0.1f, 0, 0);
                    handle2Prop.vector3Value = new Vector3(-0.1f, 0, 0);
                }
            }

            else if(newType == 2)
            {
                handle1Prop.vector3Value = Vector3.zero;
                handle2Prop.vector3Value = Vector3.zero;
            }
        }

        Vector3 newPointPos = EditorGUILayout.Vector3Field("Position : ", point.transform.localPosition);
        if(newPointPos != point.transform.localPosition)
        {
            Undo.RegisterUndo(point.transform, "Move Bezier Point");
            point.transform.localPosition = newPointPos;
        }

        if(handleStyleProp.enumValueIndex == 0)
        {
            Vector3 newPosition;

            newPosition = EditorGUILayout.Vector3Field("Handle 1", handle1Prop.vector3Value);
            if(newPosition != handle1Prop.vector3Value)
            {
                handle1Prop.vector3Value = newPosition;
                handle2Prop.vector3Value = -newPosition;
            }

            newPosition = EditorGUILayout.Vector3Field("Handle 2", handle2Prop.vector3Value);
            if(newPosition != handle2Prop.vector3Value)
            {
                handle1Prop.vector3Value = -newPosition;
                handle2Prop.vector3Value = newPosition;
            }
        }

        else if(handleStyleProp.enumValueIndex == 1)
        {
            EditorGUILayout.PropertyField(handle1Prop);
            EditorGUILayout.PropertyField(handle2Prop);
        }

        EditorGUI.indentLevel--;
        EditorGUI.indentLevel--;

        if(GUI.changed)
        {
            serObj.ApplyModifiedProperties();
            EditorUtility.SetDirty(serObj.targetObject);
        }
    }
Example #20
0
        /// <summary>
        /// 读取XML中的贝塞尔曲线内容
        /// </summary>
        /// <param name="beziernode"></param>
        /// <param name="pic"></param>
        public static void ReadBezierLine(XmlNode beziernode, PicTabPage pic)
        {
            XmlElement bezierElement   = (XmlElement)beziernode;
            int        ID              = int.Parse(bezierElement.GetAttribute("ID"));
            double     StrokeThickness = double.Parse(bezierElement.GetAttribute("StrokeThickness"));
            ///读取起始点
            XmlElement  startPoint           = (XmlElement)beziernode.SelectSingleNode("StartPoint");
            BezierPoint readStartBezierPoint = new BezierPoint();
            int         startID       = -1;
            int         startfatherID = -1;

            foreach (XmlNode node in startPoint.ChildNodes)
            {
                XmlElement nodeElenemt = (XmlElement)node;
                switch (nodeElenemt.Name)
                {
                case "PositionType":
                    readStartBezierPoint.positionType = XAribute.XPositonStyleMapping(nodeElenemt.InnerText);
                    break;

                case "LinkAributeID":
                    startID = int.Parse(nodeElenemt.InnerText);
                    break;

                case "LinkAributeFatherID":
                    startfatherID = int.Parse(nodeElenemt.InnerText);
                    break;

                default:
                    break;
                }
            }
            ///读取结束点
            XmlElement  endPoint           = (XmlElement)beziernode.SelectSingleNode("EndPoint");
            BezierPoint readEndBezierPoint = new BezierPoint();
            int         endID       = -1;
            int         endfatherID = -1;

            foreach (XmlNode node in endPoint.ChildNodes)
            {
                XmlElement nodeElenemt = (XmlElement)node;
                switch (nodeElenemt.Name)
                {
                case "PositionType":
                    readEndBezierPoint.positionType = XAribute.XPositonStyleMapping(nodeElenemt.InnerText);
                    break;

                case "LinkAributeID":
                    endID = int.Parse(nodeElenemt.InnerText);
                    break;

                case "LinkAributeFatherID":
                    endfatherID = int.Parse(nodeElenemt.InnerText);
                    break;

                default:
                    break;
                }
            }
            BezierLine readBezierLine = new BezierLine(ID);

            readBezierLine.StartPoint = readStartBezierPoint;
            readBezierLine.EndPoint   = readEndBezierPoint;
            pic.ReadCreateBezierLine(readBezierLine, startID, endID, startfatherID, endfatherID);
        }
Example #21
0
	/// <summary>
	/// 	- Adds the given point to the end of the curve ("points" array)
	/// </summary>
	/// <param name='point'>
	/// 	- The point to add.
	/// </param>
	public void AddPoint(BezierPoint point)
	{
		List<BezierPoint> tempArray = new List<BezierPoint>(points);
		tempArray.Add(point);
		points = tempArray.ToArray();
		dirty = true;
	}
    public static bool IsNearBezier(Vector2 p, BezierPoint point1, BezierPoint point2, float rad)
    {
        if (point1.curve2 != point2.curve1) {
        Debug.LogError ("Curves Not The Same");
        return false;
        }

        BezierCurve curve = point1.curve2;

        var r = curve.rect;
        r.x-=rad;
        r.y-=rad;
        r.width+=rad*2;
        r.height+=rad*2;

        if (!r.Contains (p)) {
        return false;
        }

        var nearest = NearestPointOnBezier (p,curve,0.1f,false);

        var sec = point1.curve2.aproxLength/10;

        if ((nearest-p).sqrMagnitude>=(sec*3)*(sec*3)) {
        return false;
        }

        nearest = NearestPointOnBezier (p,curve,0.01f,true);

        if ((nearest-p).sqrMagnitude<=rad*rad) {
        return true;
        }

        return false;
    }
Example #23
0
	/// <summary>
	/// 	- Get the index of the given point in this curve
	/// </summary>
	/// <returns>
	/// 	- The index, or -1 if the point is not found
	/// </returns>
	/// <param name='point'>
	/// 	- Point to search for
	/// </param>
	public int GetPointIndex(BezierPoint point)
	{
		int result = -1;
		for(int i = 0; i < points.Length; i++)
		{
			if(points[i] == point)
			{
				result = i;
				break;
			}
		}
		
		return result;
	}
 public static bool IsNearBeziers(Vector2 p, BezierPoint[] points, float rad)
 {
     for (var i=0;i<points.Length-1;i++) {
     if (IsNearBezier (p,points[i],points[i+1],rad)) {
         return true;
     }
     }
     return false;
 }
Example #25
0
	/// <summary>
	/// 	- Gets the point 't' percent along a curve
	/// 	- Automatically calculates for the number of relevant points
	/// </summary>
	/// <returns>
	/// 	- The point 't' percent along the curve
	/// </returns>
	/// <param name='p1'>
	/// 	- The bezier point at the beginning of the curve
	/// </param>
	/// <param name='p2'>
	/// 	- The bezier point at the end of the curve
	/// </param>
	/// <param name='t'>
	/// 	- Value between 0 and 1 representing the percent along the curve (0 = 0%, 1 = 100%)
	/// </param>
	public static Vector3 GetPoint(BezierPoint p1, BezierPoint p2, float t)
	{
		if(p1.handle2 != Vector3.zero)
		{
			if(p2.handle1 != Vector3.zero) return GetCubicCurvePoint(p1.position, p1.globalHandle2, p2.globalHandle1, p2.position, t);
			else return GetQuadraticCurvePoint(p1.position, p1.globalHandle2, p2.position, t);
		}
		
		else
		{
			if(p2.handle1 != Vector3.zero) return GetQuadraticCurvePoint(p1.position, p2.globalHandle1, p2.position, t);
			else return GetLinearPoint(p1.position, p2.position, t);
		}	
	}
Example #26
0
	private static void HandleAbsent(BezierPoint p)
	{
		p.handle1 = Vector3.zero;
		p.handle2 = Vector3.zero;
	}
    public static void DrawBezier(BezierPoint[] points, float rad, Color col, Texture2D tex)
    {
        rad = Mathf.Round(rad);//It is important to round the numbers otherwise it will mess up with the texture width

        if (points.Length <= 1)
        {
            return;
        }

        Vector2 topleft = new Vector2(Mathf.Infinity, Mathf.Infinity);
        Vector2 bottomright = new Vector2(0, 0);

        for (var i = 0; i < points.Length - 1; i++)
        {
            BezierCurve curve = new BezierCurve(points[i].main, points[i].control2, points[i + 1].control1, points[i + 1].main );
            points[i].curve2 = curve;
            points[i + 1].curve1 = curve;

            topleft.x = Mathf.Min(topleft.x, curve.rect.x);

            topleft.y = Mathf.Min(topleft.y, curve.rect.y);

            bottomright.x = Mathf.Max(bottomright.x, curve.rect.x + curve.rect.width);

            bottomright.y = Mathf.Max(bottomright.y, curve.rect.y + curve.rect.height);
        }

        topleft -= new Vector2(rad, rad);
        bottomright += new Vector2(rad, rad);

        var start = new Vector2(Mathf.Clamp(topleft.x, 0, tex.width), Mathf.Clamp(topleft.y, 0, tex.height));
        var width = new Vector2(Mathf.Clamp(bottomright.x - topleft.x, 0, tex.width - start.x), Mathf.Clamp(bottomright.y - topleft.y, 0, tex.height - start.y));

        Color[] pixels = tex.GetPixels((int)start.x, (int)start.y, (int)width.x, (int)width.y, 0);

        for (var y = 0; y < width.y; y++)
        {
            for (var x = 0; x < width.x; x++)
            {
                var p = new Vector2(x + start.x, y + start.y);
                if (!Mathfx.IsNearBeziers(p, points, rad + 2))
                {
                    continue;
                }

                var samples = Sample(p);
                var c = Color.black;
                var pc = pixels[(int)(y * width.x + x)];//Previous pixel color
                for (var i = 0; i < samples.Length; i++)
                {
                    if (Mathfx.IsNearBeziers(samples[i], points, rad))
                    {
                        c += col;
                    }
                    else
                    {
                        c += pc;
                    }
                }

                c /= samples.Length;

                pixels[(int)(y * width.x + x)] = c;

            }
        }

        tex.SetPixels((int)start.x, (int)start.y, (int)width.x, (int)width.y, pixels, 0);
        tex.Apply();
    }
Example #28
0
    //create bezier waypoint
    void PlaceBezierPoint(Vector3 placePos)
    {
        //create new bezier point property class
        BezierPoint newPoint = new BezierPoint();

        //instantiate waypoint gameobject
        GameObject wayp = new GameObject("Waypoint");
        //assign waypoint to the class
        newPoint.wp = wayp.transform;

        //same as in PlaceWaypoint(),
        //but we have to restrict x, z values due to minor issues with bezier points
        if (bwpList.Count == 0)
            bezierPathMan.transform.position = new Vector3(0, placePos.y, 0);

        //overwrite bezier points for the first point,
        //because some weird stuff is going on when repositioning the path
        //once finished, the exact bezier positions will get recalculated anyways
        if (bwpList.Count == 1)
        {
            bwpList[0].bp = new[] { bwpList[0].wp.transform.position - new Vector3(2, 0, 0),
                                    bwpList[0].wp.transform.position + new Vector3(0, 0, 2) };
        }

        //position current waypoint at clicked position in scene view
        wayp.transform.position = placePos;

        //look up and parent it to the defined path
        wayp.transform.parent = bezierPathMan.transform;
        //zero out its y-value to correctly work in 2D space
        Vector3 localPos = wayp.transform.localPosition;
        localPos.y = 0f;
        wayp.transform.localPosition = localPos;

        //create new array with bezier point handle positions for this waypoint
        newPoint.bp = new[] { placePos - new Vector3(2, 0, 0),
                              placePos + new Vector3(0, 0, 2) };

        //add waypoint to the list of waypoints
        bezierPathMan.points.Add(newPoint);
        //add waypoint to temporary list
        bwpList.Add(newPoint);
        //rename waypoint to match the list count
        wayp.name = "Waypoint" + (bwpList.Count - 1);
    }
Example #29
0
	private static void HandleBroken(BezierPoint p){
		Handles.color = Color.cyan;

		Vector3 newGlobal1 = Handles.FreeMoveHandle(p.globalHandle1, Quaternion.identity, HandleUtility.GetHandleSize(p.globalHandle1)*0.15f, Vector3.zero, Handles.SphereCap);
		Vector3 newGlobal2 = Handles.FreeMoveHandle(p.globalHandle2, Quaternion.identity, HandleUtility.GetHandleSize(p.globalHandle2)*0.15f, Vector3.zero, Handles.SphereCap);
		
		if(newGlobal1 != p.globalHandle1)
		{
			Undo.RecordObject(p, "Move Handle");
			p.globalHandle1 = newGlobal1;
		}
		
		if(newGlobal2 != p.globalHandle2)
		{
			Undo.RecordObject(p, "Move Handle");
			p.globalHandle2 = newGlobal2;
		}
	}
Example #30
0
 public static void DrawCurve(BezierPoint p1, BezierPoint p2, float resolution)
 {
     DrawCurve(p1, p2, GetNumPoints(p1, p2, resolution));
 }
    //adds a waypoint when clicking on the "+" button in the inspector
    private void AddWaypointAtIndex(int index)
    {
        //register all scene objects so we can undo to this current state
        //before adding this waypoint easily
        Undo.RegisterSceneUndo("WPAdd");

        //create a new waypoint property class
        BezierPoint point = new BezierPoint();

        //create new waypoint gameobject
        GameObject wp = new GameObject("Waypoint");
        //set its position to the last one
        wp.transform.position = script.points[index].wp.position;
        //assign it to the class
        point.wp = wp.transform;
        //assign new bezier point positions
        point.bp = new[] { wp.transform.position - new Vector3(2f, 0f, 0f),
                           wp.transform.position + new Vector3(0, 0, 2f) };

        //parent it to the path gameobject
        wp.transform.parent = script.transform;
        //zero out its y-value to correctly work in 2D space
        Vector3 localPos = wp.transform.localPosition;
        localPos.y = 0f;
        wp.transform.localPosition = localPos;

        //finally, insert this new waypoint after the one clicked in the list
        script.points.Insert(index + 1, point);
    }
    public override void OnInspectorGUI()
    {
        //don't draw inspector fields if the path contains less than 2 points
        //(a path with less than 2 points really isn't a path)
        if (script.points.Count < 2)
            return;

        //create new color fields for editing waypoint gizmo colors
        script.color1 = EditorGUILayout.ColorField("Color1", script.color1);
        script.color2 = EditorGUILayout.ColorField("Color2", script.color2);
        script.color3 = EditorGUILayout.ColorField("Color3", script.color3);

        //let iTween calculate path length of all waypoints
        float pathLength = iTween.PathLength(script.waypoints);
        //path length label, show calculated path length
        GUILayout.Label("Straight Path Length: " + pathLength);

        //checkbox Field to enable editable path properties
        EditorGUILayout.BeginHorizontal();
        script.showGizmos = EditorGUILayout.Toggle("Show Gizmos", script.showGizmos);
        EditorGUILayout.EndHorizontal();

        //check if the path gameobject position has changed since the last call
        if (!script.showGizmos && script.transform.position != oldGizmoPos)
        {
            //if not in edit mode, ignore user input
            script.transform.position = oldGizmoPos;
        }
        else
        {
            //calculate the difference between the two positions
            Vector3 difPos = script.transform.position - oldGizmoPos;
            oldGizmoPos = script.transform.position;

            if (difPos != Vector3.zero)
            {
                //enable edit mode when moving the path object
                script.showGizmos = true;
                //add the difference to the bezier points per waypoint,
                //so they are moving with the path
                for (int i = 0; i < script.points.Count; i++)
                {
                    script.points[i].bp[0] += difPos;
                    script.points[i].bp[1] += difPos;
                }
            }
        }

        //hide following settings
        if (!script.showGizmos) return;

        //Float Field to modify the distance between generated path points
        EditorGUILayout.BeginHorizontal();
        script.spacing = EditorGUILayout.FloatField("Spacing", script.spacing);
        EditorGUILayout.EndHorizontal();

        //Int Slider to modify the smoothing factor of the final path
        EditorGUILayout.BeginHorizontal();
        script.interpolations = EditorGUILayout.IntSlider("Interpolations", script.interpolations, 0, 4);
        EditorGUILayout.EndHorizontal();

        //waypoint index header
        GUILayout.Label("Waypoints: ", EditorStyles.boldLabel);

        //loop through the waypoint array
        for (int i = 0; i < script.points.Count; i++)
        {
            GUILayout.BeginHorizontal();
            //indicate each array slot with index number in front of it
            GUILayout.Label((i + 1) + ".", GUILayout.Width(20));
            //create an object field for every waypoint
            var result = EditorGUILayout.ObjectField(script.points[i].wp, typeof(Transform), true) as Transform;

            //if the object field has changed, set waypoint to new input
            if (GUI.changed)
                script.points[i].wp = result;

            //display an "Add Waypoint" button for every array row except the last one
            //on click we call AddWaypointAtIndex() to insert a new waypoint slot AFTER the selected slot
            if (i < script.points.Count - 1 && GUILayout.Button("+", GUILayout.Width(30f)))
            {
                AddWaypointAtIndex(i);
                break;
            }

            //display an "Remove Waypoint" button for every array row except the first and last one
            //on click we call RemoveWaypointAtIndex() to delete the selected waypoint slot
            if (i > 0 && i < script.points.Count - 1 && GUILayout.Button("-", GUILayout.Width(30f)))
            {
                RemoveWaypointAtIndex(i);
                break;
            }

            GUILayout.EndHorizontal();
        }

        EditorGUILayout.Space();

        //invert direction of whole path
        if (GUILayout.Button("Invert Direction"))
        {
            //register all scene objects so we can undo to this current state
            //before inverting all waypoints easily
            Undo.RegisterSceneUndo("WPInvert");

            //Array.Copy() just gives us references and would change both arrays,
            //so we classically create a new array with length of the current one,
            //loop through them and copy all position data to the newly created array
            BezierPoint[] waypointCache = new BezierPoint[script.points.Count];
            //cache "old value"
            for (int i = 0; i < waypointCache.Length; i++)
            {
                waypointCache[i] = script.points[i];
            }
            //reverse order based on the old list
            for (int i = 0; i < waypointCache.Length; i++)
            {
                script.points[waypointCache.Length - 1 - i] = waypointCache[i];
            }
            //rename the first and last waypoint to match the new order
            script.points[0].wp.name = "WaypointStart";
            script.points[script.points.Count - 1].wp.name = "WaypointEnd";
        }

        EditorGUILayout.Space();

        //draw object field for waypoint prefab
        script.waypointPrefab = (GameObject)EditorGUILayout.ObjectField("Waypoint Prefab", script.waypointPrefab, typeof(GameObject), true);

        //replace all waypoints with the prefab
        if (GUILayout.Button("Replace Waypoints"))
        {
            //abort if no waypoint is set
            if (script.waypointPrefab == null)
            {
                Debug.LogWarning("No Waypoint Prefab set. Aborting.");
                return;
            }

            ReplaceWaypoints();
        }

        if (GUI.changed)
            SceneView.RepaintAll();
    }
    void test()
    {
        float startTime = Time.realtimeSinceStartup;
        var w = 100;
        var h = 100;
        var p1 = new BezierPoint(new Vector2(10, 0), new Vector2(5, 20), new Vector2(20, 0));
        var p2 = new BezierPoint(new Vector2(50, 10), new Vector2(40, 20), new Vector2(60, -10));
        var c = new BezierCurve(p1.main, p1.control2, p2.control1, p2.main);
        p1.curve2 = c;
        p2.curve1 = c;
        Vector2 elapsedTime = new Vector2((Time.realtimeSinceStartup - startTime) * 10, 0);
        float startTime2 = Time.realtimeSinceStartup;
        for (var i = 0; i < w * h; i++)
        {
            Mathfx.IsNearBezier(new Vector2(Random.value * 80, Random.value * 30), p1, p2, 10);
        }

        Vector2 elapsedTime2 = new Vector2((Time.realtimeSinceStartup - startTime2) * 10, 0);
        Debug.Log("Drawing took " + elapsedTime.ToString() + "  " + elapsedTime2.ToString());
    }
Example #34
0
 public void AddPoint(BezierPoint point)
 {
     _points.Add(point);
     _dirty = true;
 }