public Vector2[] CalculateEvenlySpacedPoints(float spacing, float resolution = 1) { List <Vector2> evenlySpacedPoints = new List <Vector2>(); evenlySpacedPoints.Add(Curve[0]); Vector2 previousPoint = Curve[0]; float dstSinceLastEvenPoint = 0; for (int segmentIndex = 0; segmentIndex < Curve.NumSegments; segmentIndex++) { Vector2[] p = Curve.GetPointsInSegment(segmentIndex); float controlNetLength = Vector2.Distance(p[0], p[1]) + Vector2.Distance(p[1], p[2]) + Vector2.Distance(p[2], p[3]); float estimatedCurveLength = Vector2.Distance(p[0], p[3]) + controlNetLength / 2f; int divisions = Mathf.CeilToInt(estimatedCurveLength * resolution * 10); float t = 0; while (t <= 1) { t += 1f / divisions; Vector2 pointOnCurve = Bezier.EvaluateCubic(p[0], p[1], p[2], p[3], t); dstSinceLastEvenPoint += Vector2.Distance(previousPoint, pointOnCurve); while (dstSinceLastEvenPoint >= spacing) { float overshootDst = dstSinceLastEvenPoint - spacing; Vector2 newEvenlySpacedPoint = pointOnCurve + (previousPoint - pointOnCurve).normalized * overshootDst; evenlySpacedPoints.Add(newEvenlySpacedPoint); dstSinceLastEvenPoint = overshootDst; previousPoint = newEvenlySpacedPoint; } previousPoint = pointOnCurve; } } return(evenlySpacedPoints.ToArray()); }
void Input() { Event guiEvent = Event.current; Vector2 mousePos = HandleUtility.GUIPointToWorldRay(guiEvent.mousePosition).origin; if (guiEvent.type == EventType.MouseDown && guiEvent.shift) { if (guiEvent.button == 0) { if (selectedSegmentIndex != -1) { Undo.RecordObject(curve.Creator, "Split segment"); curve.SplitSegment(mousePos, selectedSegmentIndex); } else if (!curve.IsClosed) { Undo.RecordObject(curve.Creator, "Add segment"); curve.AddSegment(mousePos); } } } // if (guiEvent.type == EventType.MouseDown && guiEvent.control && guiEvent.button == 0) // { // if (_selectedSegmentIndex != -1) // { // Undo.RecordObject(_curve.Creator, "Split segment"); // _curve.SplitSegment(mousePos, _selectedSegmentIndex); // } // } if (guiEvent.type == EventType.MouseDown && guiEvent.button == 1) { float minDstToAnchor = curve.Creator.AnchorDiameter * .5f; int closestAnchorIndex = -1; for (int i = 0; i < curve.NumPoints; i += 3) { float dst = Vector2.Distance(mousePos, curve[i]); if (dst < minDstToAnchor) { minDstToAnchor = dst; closestAnchorIndex = i; } } if (closestAnchorIndex != -1) { Undo.RecordObject(curve.Creator, "Delete segment"); curve.DeleteSegment(closestAnchorIndex); } } if (guiEvent.type == EventType.MouseMove) { float minDstToSegment = SEGMENT_SELECT_DISTANCE_THRESHOLD; int newSelectedSegmentIndex = -1; for (int i = 0; i < curve.NumSegments; i++) { Vector2[] points = curve.GetPointsInSegment(i); Handles.DrawBezier(points[0], points[3], points[1], points[2], Color.green, null, 2); float dst = HandleUtility.DistancePointBezier(mousePos, points[0], points[3], points[1], points[2]); if (dst < minDstToSegment) { minDstToSegment = dst; newSelectedSegmentIndex = i; } } if (newSelectedSegmentIndex != selectedSegmentIndex) { selectedSegmentIndex = newSelectedSegmentIndex; HandleUtility.Repaint(); } } HandleUtility.AddDefaultControl(0); }