1
0
mirror of https://github.com/Cardidi/dotween-upm-fork.git synced 2025-12-21 09:46:04 +08:00
2015-03-18 19:30:48 +01:00

101 lines
2.6 KiB
C#

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class GoSplineStraightLineSolver : AbstractGoSplineSolver
{
private Dictionary<int, float> _segmentStartLocations;
private Dictionary<int, float> _segmentDistances;
private int _currentSegment;
public GoSplineStraightLineSolver( List<Vector3> nodes )
{
_nodes = nodes;
}
#region AbstractGoSplineSolver
public override void buildPath()
{
// we need at least 3 nodes (more than 1 segment) to bother with building
if( _nodes.Count < 3 )
return;
// we dont care about the first node for distances because they are always t:0 and len:0 and we dont need the first or last for locations
_segmentStartLocations = new Dictionary<int, float>( _nodes.Count - 2 );
_segmentDistances = new Dictionary<int, float>( _nodes.Count - 1 );
for( var i = 0; i < _nodes.Count - 1; i++ )
{
// calculate the distance to the next node
var distance = Vector3.Distance( _nodes[i], _nodes[i + 1] );
_segmentDistances.Add( i, distance );
_pathLength += distance;
}
// now that we have the total length we can loop back through and calculate the segmentStartLocations
var accruedRouteLength = 0f;
for( var i = 0; i < _segmentDistances.Count - 1; i++ )
{
accruedRouteLength += _segmentDistances[i];
_segmentStartLocations.Add( i + 1, accruedRouteLength / _pathLength );
}
}
public override void closePath()
{
// add a node to close the route if necessary
if( _nodes[0] != _nodes[_nodes.Count - 1] )
_nodes.Add( _nodes[0] );
}
public override Vector3 getPoint( float t )
{
return getPointOnPath( t );
}
public override Vector3 getPointOnPath( float t )
{
// we need at least 3 nodes (more than 1 segment) to bother using the look up tables. else we just lerp directly from
// node 1 to node 2
if( _nodes.Count < 3 )
return Vector3.Lerp( _nodes[0], _nodes[1], t );
// which segment are we on?
_currentSegment = 0;
foreach( var info in _segmentStartLocations )
{
if( info.Value < t )
{
_currentSegment = info.Key;
continue;
}
break;
}
// now we need to know the total distance travelled in all previous segments so we can subtract it from the total
// travelled to get exactly how far along the current segment we are
var totalDistanceTravelled = t * _pathLength;
var i = _currentSegment - 1; // we want all the previous segment lengths
while( i >= 0 )
{
totalDistanceTravelled -= _segmentDistances[i];
--i;
}
return Vector3.Lerp( _nodes[_currentSegment], _nodes[_currentSegment + 1], totalDistanceTravelled / _segmentDistances[_currentSegment] );
}
#endregion
}