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 output ) { SampleMultiple( new Range( 0, 1 ), numSamples, output ); } public virtual void SampleMultiple( Range range, int numSamples, List 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 ); } } }