/// <summary> /// Undo-complient version of CurvyUtility.JoinSpline() /// </summary> /// <param name="sourceCP">a Control Point of the source spline</param> /// <param name="destCP">the Control Point of the destination spline</param> public static void UndoJoinSpline(CurvySplineSegment sourceCP, CurvySplineSegment destCP) { #if !OLD_UNDO if (!sourceCP || !destCP) { return; } CurvySpline src = sourceCP.Spline; CurvySpline dst = destCP.Spline; if (src == dst) { return; } for (int i = 0; i < src.ControlPointCount; i++) { Undo.RecordObject(src.ControlPoints[i].gameObject, "Join Spline"); Undo.SetTransformParent(src.ControlPoints[i].Transform, dst.Transform, "Join Spline"); src.ControlPoints[i]._ReSettle(); } dst.ControlPoints.InsertRange(destCP.ControlPointIndex + 1, src.ControlPoints); dst._RenameControlPointsByIndex(); dst.RefreshImmediately(true, true, false); Undo.DestroyObjectImmediate(src.gameObject); #endif }
// Update is called once per frame void Update() { // Add Control Point by mouseclick if (Input.GetMouseButtonDown(0)) { Vector3 p = Input.mousePosition; p.z = 10; p = Camera.main.ScreenToWorldPoint(p); mSpline.Add(p); // remove segments we've already passed if (RemoveUnusedSegments) { var current = Walker.CurrentSegment; if (current) { // If we're not on the first segment, we can savely remove some Control Points! // NOTE: While we usually would have used current.SegmentIndex to make it work with disabled AutoEndTangents (where the first CP isn't the first segment), // we use ControlPointIndex here for single good reason: // We don't want to refresh the spline each time we delete a segment, but just at the end of the deletion process. Deleting a ControlPoint resets the segment hierarchy // (it will be repopulated during Refresh), so we can't use SegmentIndex nor mSpline[n] to access the first segment in the deletion loop. int curIdx = current.ControlPointIndex; int toDelete = curIdx - 2; // keep two extra segments to prevent curve change of active segment if (toDelete > 0) { for (int i = 0; i < toDelete; i++) { mSpline.Delete(mSpline.ControlPoints[0], false); // don't refresh! Warning: This resets Segment info of the spline! } mSpline.RefreshImmediately(); // now refresh the spline } } } } }
/// <summary> /// Undo-complient version of CurvyUtility.SplitSpline() /// </summary> /// <param name="firstCP">the first Control Point of the new spline</param> /// <returns>the new spline</returns> public static CurvySpline UndoSplitSpline(CurvySplineSegment firstCP) { #if OLD_UNDO Undo.RegisterSceneUndo("Split Spline"); return(CurvyUtility.SplitSpline(firstCP)); #else CurvySpline old = firstCP.Spline; CurvySpline spl = CurvySpline.Create(old); Undo.RegisterCreatedObjectUndo(spl.gameObject, "Split Spline"); spl.name = old.name + "_parted"; // Move CPs var affected = old.ControlPoints.GetRange(firstCP.ControlPointIndex, old.ControlPointCount - firstCP.ControlPointIndex); for (int i = 0; i < affected.Count; i++) { Undo.RecordObject(affected[i].gameObject, "Split Spline"); Undo.SetTransformParent(affected[i].Transform, spl.Transform, "Split Spline"); affected[i]._ReSettle(); } old.ControlPoints.Clear(); old.RefreshImmediately(true, true, false); spl._RenameControlPointsByIndex(); spl.RefreshImmediately(true, true, false); return(spl); #endif }
CurvySpline CreateSpline(CurvyInterpolation type, int points, int granularity) { CurvySpline spl = CurvySpline.Create(); spl.Interpolation = type; spl.Granularity = granularity; spl.Closed = false; spl.ShowGizmos = false; spl.AutoEndTangents = true; for (int i = 0; i < points; i++) { spl.Add(null, false).Position = Random.insideUnitCircle * 10; } spl.RefreshImmediately(); return(spl); }
/// <summary> /// Splits a spline /// </summary> /// <param name="firstCP">the first Control Point of the new spline</param> /// <returns>the new spline</returns> public static CurvySpline SplitSpline(CurvySplineSegment firstCP) { CurvySpline old = firstCP.Spline; CurvySpline spl = CurvySpline.Create(old); spl.name = old.name + "_parted"; // Move CPs var affected = old.ControlPoints.GetRange(firstCP.ControlPointIndex, old.ControlPointCount - firstCP.ControlPointIndex); for (int i = 0; i < affected.Count; i++) { affected[i].Transform.parent = spl.Transform; affected[i]._ReSettle(); } old.ControlPoints.Clear(); old.RefreshImmediately(true, true, false); spl._RenameControlPointsByIndex(); spl.RefreshImmediately(true, true, false); return(spl); }
/// <summary> /// Rearrange the spline to have a new first Control Point. /// </summary> /// <param name="newStartCP">the Control Point to become the first Control Point</param> public static void setFirstCP(CurvySplineSegment newStartCP) { CurvySpline spl = newStartCP.Spline; if (newStartCP.ControlPointIndex <= 0) { return; } CurvySplineSegment[] toMove = new CurvySplineSegment[newStartCP.ControlPointIndex]; for (int i = 0; i < newStartCP.ControlPointIndex; i++) { toMove[i] = spl.ControlPoints[i]; } foreach (CurvySplineSegment seg in toMove) { spl.ControlPoints.Remove(seg); spl.ControlPoints.Add(seg); } spl._RenameControlPointsByIndex(); spl.RefreshImmediately(true, true, false); }
/// <summary> /// Join a spline by inserting all source Control Points after a destination Control Point /// </summary> /// <param name="sourceCP">a Control Point of the source spline</param> /// <param name="destCP">the Control Point of the destination spline</param> public static void JoinSpline(CurvySplineSegment sourceCP, CurvySplineSegment destCP) { if (!sourceCP || !destCP) { return; } CurvySpline src = sourceCP.Spline; CurvySpline dst = destCP.Spline; if (src == dst) { return; } for (int i = 0; i < src.ControlPointCount; i++) { src.ControlPoints[i].Transform.parent = dst.Transform; src.ControlPoints[i]._ReSettle(); } dst.ControlPoints.InsertRange(destCP.ControlPointIndex + 1, src.ControlPoints); dst._RenameControlPointsByIndex(); dst.RefreshImmediately(true, true, false); src.Destroy(); }
/// <summary> /// Flips the direction of a spline, i.e. the first Control Point will become the last and vice versa. /// </summary> public static void FlipSpline(CurvySpline spline) { spline.ControlPoints.Reverse(); spline._RenameControlPointsByIndex(); spline.RefreshImmediately(true, true, false); }
// Update is called once per frame void Update() { // Add Control Point by mouseclick mSpline.RefreshImmediately(); //mSpline.RefreshImmediately(); }