using System;
using System.Collections;
using System.Collections.Generic;
using Unity.Mathematics;
namespace UnityEngine.Splines
{
///
/// Describes the direction that a interpolates. Use and
/// to create paths that interpolate along a in either a forward
/// or backward direction.
///
///
///
public enum SliceDirection
{
///
/// The interpolates along the direction of the referenced spline.
///
Forward,
///
/// The interpolates in the reverse direction of the referenced spline.
///
Backward
}
///
/// Describes a subset of knot indices in a . The range might iterate in either the
/// forward or backward direction.
///
[Serializable]
public struct SplineRange : IEnumerable
{
[SerializeField]
int m_Start;
[SerializeField]
int m_Count;
[SerializeField]
SliceDirection m_Direction;
///
/// The inclusive first index, starting at 0.
///
public int Start
{
get => m_Start;
set => m_Start = value;
}
///
/// The inclusive end index of this range.
///
public int End => this[Count - 1];
///
/// Returns the number of indices.
///
public int Count
{
get => m_Count;
set => m_Count = math.max(value, 0);
}
///
/// The direction that this range interpolates. increments
/// the knot index when it iterates, whereas decrements this index.
///
public SliceDirection Direction
{
get => m_Direction;
set => m_Direction = value;
}
///
/// Creates a new from a start index and count.
///
/// The inclusive first index of a range.
/// The number of elements this range encompasses. This value might be negative,
/// which is shorthand to call the constructor with an explicit parameter.
///
public SplineRange(int start, int count) : this(start, count,
count < 0 ? SliceDirection.Backward : SliceDirection.Forward)
{
}
///
/// Creates a new from a start index and count.
///
/// The inclusive first index of a range.
/// The number of elements this range encompasses.
/// Whether when iterating this range it is incrementing from start to start + count, or
/// decrementing from start to start - count.
///
public SplineRange(int start, int count, SliceDirection direction)
{
m_Start = start;
m_Count = math.abs(count);
m_Direction = direction;
}
///
/// Get or set the knot index at an index .
/// This indexer allows you to write a for loop to iterate through a range without needing to know in which
/// direction the range is iterating.
///
///
///
/// // Create a new range into an existing Spline starting at knot 5, and interpolating the span of 3 knots.
/// // range[0,1,2] will map to { 6, 5, 4 } respectively.
/// var range = new SplineRange(6, 3, SplineDirection.Backward);
///
///
/// The zero-based index of the element to get or set.
public int this[int index] => Direction == SliceDirection.Backward ? m_Start - index : m_Start + index;
///
/// Get an enumerator that iterates through the index collection. Note that this will either increment or
/// decrement indices depending on the value of the property.
///
/// An IEnumerator that is used to iterate the collection.
public IEnumerator GetEnumerator() => new SplineRangeEnumerator(this);
///
/// Gets an enumerator that iterates through the index collection. It either increments or
/// decrements indices depending on the value of the property.
///
/// Returns an IEnumerator that is used to iterate the collection.
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
///
/// A struct for iterating a .
///
public struct SplineRangeEnumerator : IEnumerator
{
int m_Index, m_Start, m_End, m_Count;
bool m_Reverse;
///
/// Advances the enumerator to the next element of the collection.
///
/// Returns true if the enumerator was successfully advanced to the next element;
/// false if the enumerator has passed the end of the collection.
public bool MoveNext() => ++m_Index < m_Count;
///
/// Sets the enumerator to its initial position, which is before the first element in the collection.
///
public void Reset() => m_Index = -1;
///
/// Gets the element in the collection at the current position of the enumerator.
///
public int Current => m_Reverse ? m_End - m_Index : m_Start + m_Index;
object IEnumerator.Current => Current;
///
/// Constructor for an IEnumerator of a .
///
/// The to iterate.
public SplineRangeEnumerator(SplineRange range)
{
m_Index = -1;
m_Reverse = range.Direction == SliceDirection.Backward;
int a = range.Start,
b = m_Reverse ? range.Start - range.Count : range.Start + range.Count;
m_Start = math.min(a, b);
m_End = math.max(a, b);
m_Count = range.Count;
}
///
/// IDisposable implementation. SplineSliceEnumerator does not allocate any resources.
///
public void Dispose() { }
}
///
/// Returns a string summary of this range.
///
/// Returns a string summary of this range.
public override string ToString() => $"{{{Start}..{End}}}";
}
}