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

88 lines
2.6 KiB
C#

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class GoSplineCatmullRomSolver : AbstractGoSplineSolver
{
public GoSplineCatmullRomSolver( List<Vector3> nodes )
{
_nodes = nodes;
}
#region AbstractGoSplineSolver
// closing a Catmull-Rom spline: http://cl.ly/GOZv
public override void closePath()
{
// first, remove the control points
_nodes.RemoveAt( 0 );
_nodes.RemoveAt( _nodes.Count - 1 );
// if the first and last node are not the same add one
if( _nodes[0] != _nodes[_nodes.Count - 1] )
_nodes.Add( _nodes[0] );
// figure out the distances from node 0 to the first node and the second to last node (remember above
// we made the last node equal to the first so node 0 and _nodes.Count - 1 are identical)
var distanceToFirstNode = Vector3.Distance( _nodes[0], _nodes[1] );
var distanceToLastNode = Vector3.Distance( _nodes[0], _nodes[_nodes.Count - 2] );
// handle the first node. we want to use the distance to the LAST (opposite segment) node to figure out where this control point should be
var distanceToFirstTarget = distanceToLastNode / Vector3.Distance( _nodes[1], _nodes[0] );
var lastControlNode = ( _nodes[0] + ( _nodes[1] - _nodes[0] ) * distanceToFirstTarget );
// handle the last node. for this one, we want the distance to the first node for the control point but it should
// be along the vector to the last node
var distanceToLastTarget = distanceToFirstNode / Vector3.Distance( _nodes[_nodes.Count - 2], _nodes[0] );
var firstControlNode = ( _nodes[0] + ( _nodes[_nodes.Count - 2] - _nodes[0] ) * distanceToLastTarget );
_nodes.Insert( 0, firstControlNode );
_nodes.Add( lastControlNode );
}
public override Vector3 getPoint( float t )
{
int numSections = _nodes.Count - 3;
int currentNode = Mathf.Min( Mathf.FloorToInt( t * (float)numSections ), numSections - 1 );
float u = t * (float)numSections - (float)currentNode;
Vector3 a = _nodes[currentNode];
Vector3 b = _nodes[currentNode + 1];
Vector3 c = _nodes[currentNode + 2];
Vector3 d = _nodes[currentNode + 3];
return .5f *
(
( -a + 3f * b - 3f * c + d ) * ( u * u * u )
+ ( 2f * a - 5f * b + 4f * c - d ) * ( u * u )
+ ( -a + c ) * u
+ 2f * b
);
}
public override void drawGizmos()
{
if( _nodes.Count < 2 )
return;
// draw the control points
var originalColor = Gizmos.color;
Gizmos.color = new Color( 1, 1, 1, 0.3f );
Gizmos.DrawLine( _nodes[0], _nodes[1] );
Gizmos.DrawLine( _nodes[_nodes.Count - 1], _nodes[_nodes.Count - 2] );
Gizmos.color = originalColor;
}
#endregion
}