119 lines
4.9 KiB
C#
119 lines
4.9 KiB
C#
|
namespace Dreamteck.Splines
|
||
|
{
|
||
|
using System.Collections;
|
||
|
using System.Collections.Generic;
|
||
|
using UnityEngine;
|
||
|
|
||
|
public static class SplineUtility
|
||
|
{
|
||
|
public enum MergeSide { Start, End }
|
||
|
|
||
|
/// <summary>
|
||
|
/// Merges two spline objects into one. The result will be merged into <paramref name="baseSpline"/>
|
||
|
/// </summary>
|
||
|
/// <param name="baseSpline">The base spline object that</param>
|
||
|
/// <param name="addedSpline">The object that will be merged into the base spline</param>
|
||
|
/// <param name="side">Which side of the base spline to append to - beginning or end?</param>
|
||
|
/// <param name="mergeEndpoints">Should the end points of the splines be merged or should they be bridged?</param>
|
||
|
/// <param name="destroyAddedSpline">If true, the added spline's game object will be destroyed after merge</param>
|
||
|
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<SplinePoint> pointsList = new List<SplinePoint>();
|
||
|
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<Node> mergedNodes = new List<Node>();
|
||
|
List<int> mergedIndices = new List<int>();
|
||
|
|
||
|
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);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|