77 lines
2.0 KiB
C#
77 lines
2.0 KiB
C#
|
using Godot;
|
||
|
using System.Collections;
|
||
|
using System.Collections.Generic;
|
||
|
|
||
|
namespace Rokojori
|
||
|
{
|
||
|
public abstract class Curve3
|
||
|
{
|
||
|
float _gradientSamplingRange = Mathf.Pow( 10f, -13f );
|
||
|
public abstract Vector3 SampleAt( float t );
|
||
|
|
||
|
public virtual void SampleMultiple( int numSamples, List<Vector3> output )
|
||
|
{
|
||
|
SampleMultiple( new Range( 0, 1 ), numSamples, output );
|
||
|
}
|
||
|
|
||
|
public virtual void SampleMultiple( Range range, int numSamples, List<Vector3> output )
|
||
|
{
|
||
|
|
||
|
var diff = range.length / ( numSamples - 1 ) ;
|
||
|
|
||
|
for ( var i = 0 ; i < numSamples; i++ )
|
||
|
{
|
||
|
var t = range.min + i * diff;
|
||
|
output.Add( SampleAt( t ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public virtual Vector3 GradientAt( float t )
|
||
|
{
|
||
|
|
||
|
return SampleAt( t + _gradientSamplingRange ) - SampleAt( t - _gradientSamplingRange );
|
||
|
}
|
||
|
|
||
|
public virtual float ComputeLength( int numSamples )
|
||
|
{
|
||
|
return ComputeSubLength( Range.Of_01 , numSamples );
|
||
|
}
|
||
|
|
||
|
public virtual float ComputeSubLength( Range range, int numSamples )
|
||
|
{
|
||
|
var diff = range.length / ( numSamples - 1 ) ;
|
||
|
var it = SampleAt( range.min );
|
||
|
var length = 0f;
|
||
|
|
||
|
for ( var i = 1 ; i < numSamples; i++ )
|
||
|
{
|
||
|
var t = range.min + i * diff;
|
||
|
var next = SampleAt( t );
|
||
|
length += ( next - it ).Length();
|
||
|
it = next;
|
||
|
}
|
||
|
|
||
|
return length;
|
||
|
}
|
||
|
|
||
|
public virtual int ComputeNumSamplesFor( Range range,
|
||
|
float minimumDistance, int minSamples = 2,
|
||
|
int numSamplesForLengthComputation = -1 )
|
||
|
{
|
||
|
if ( minSamples < 2 )
|
||
|
{ minSamples = 2; }
|
||
|
|
||
|
if ( numSamplesForLengthComputation <= 0 )
|
||
|
{ numSamplesForLengthComputation = minSamples * 4; }
|
||
|
|
||
|
float distance = ComputeSubLength( range, numSamplesForLengthComputation );
|
||
|
float numFloatingCuts = distance / minimumDistance;
|
||
|
int numSamples = Mathf.CeilToInt( numFloatingCuts );
|
||
|
|
||
|
return Mathf.Max( minSamples, numSamples );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
}
|
||
|
}
|