namespace Dreamteck.Splines { using System.Collections; using System.Collections.Generic; using UnityEngine; public static class SplineUtility { public enum MergeSide { Start, End } /// /// Merges two spline objects into one. The result will be merged into /// /// The base spline object that /// The object that will be merged into the base spline /// Which side of the base spline to append to - beginning or end? /// Should the end points of the splines be merged or should they be bridged? /// If true, the added spline's game object will be destroyed after merge public static void Merge(SplineComputer baseSpline, SplineComputer addedSpline, MergeSide side, bool mergeEndpoints = false, bool destroyAddedSpline = false) { SplinePoint[] mergedPoints = addedSpline.GetPoints(); SplinePoint[] basePoints = baseSpline.GetPoints(); List pointsList = new List(); SplinePoint[] points; if (!mergeEndpoints) points = new SplinePoint[mergedPoints.Length + basePoints.Length]; else points = new SplinePoint[mergedPoints.Length + basePoints.Length - 1]; if (side == MergeSide.End) { if (side == MergeSide.Start) { for (int i = 0; i < basePoints.Length; i++) pointsList.Add(basePoints[i]); for (int i = mergeEndpoints ? 1 : 0; i < mergedPoints.Length; i++) pointsList.Add(mergedPoints[i]); } else { for (int i = 0; i < basePoints.Length; i++) pointsList.Add(basePoints[i]); for (int i = 0; i < mergedPoints.Length - (mergeEndpoints ? 1 : 0); i++) pointsList.Add(mergedPoints[(mergedPoints.Length - 1) - i]); } } else { if (side == MergeSide.Start) { for (int i = 0; i < mergedPoints.Length - (mergeEndpoints ? 1 : 0); i++) pointsList.Add(mergedPoints[(mergedPoints.Length - 1) - i]); for (int i = 0; i < basePoints.Length; i++) pointsList.Add(basePoints[i]); } else { for (int i = mergeEndpoints ? 1 : 0; i < mergedPoints.Length; i++) pointsList.Add(mergedPoints[i]); for (int i = 0; i < basePoints.Length; i++) pointsList.Add(basePoints[i]); } } points = pointsList.ToArray(); double mergedPercent = (double)(mergedPoints.Length - 1) / (points.Length - 1); double from = 0.0; double to = 1.0; if (side == MergeSide.End) { from = 1.0 - mergedPercent; to = 1.0; } else { from = 0.0; to = mergedPercent; } List mergedNodes = new List(); List mergedIndices = new List(); for (int i = 0; i < addedSpline.pointCount; i++) { Node node = addedSpline.GetNode(i); if (node != null) { mergedNodes.Add(node); mergedIndices.Add(i); addedSpline.DisconnectNode(i); i--; } } SplineUser[] subs = addedSpline.GetSubscribers(); for (int i = 0; i < subs.Length; i++) { addedSpline.Unsubscribe(subs[i]); subs[i].spline = baseSpline; subs[i].clipFrom = DMath.Lerp(from, to, subs[i].clipFrom); subs[i].clipTo = DMath.Lerp(from, to, subs[i].clipTo); } baseSpline.SetPoints(points); if (side == MergeSide.Start) { baseSpline.ShiftNodes(0, baseSpline.pointCount - 1, addedSpline.pointCount); for (int i = 0; i < mergedNodes.Count; i++) { baseSpline.ConnectNode(mergedNodes[i], mergedIndices[i]); } } else { for (int i = 0; i < mergedNodes.Count; i++) { int connectIndex = mergedIndices[i] + basePoints.Length; if (mergeEndpoints) connectIndex--; baseSpline.ConnectNode(mergedNodes[i], connectIndex); } } if (destroyAddedSpline) { Object.Destroy(addedSpline.gameObject); } } } }