mirror of
https://github.com/Cardidi/dotween-upm-fork.git
synced 2025-12-21 17:56:08 +08:00
88 lines
2.6 KiB
C#
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
|
|
|
|
}
|