93 lines
2.3 KiB
C#
93 lines
2.3 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System;
|
|
using System.Reflection;
|
|
using System.Text.RegularExpressions;
|
|
using Godot;
|
|
|
|
namespace Rokojori
|
|
{
|
|
public class MinMaxSearch<T>
|
|
{
|
|
Func<T,T,float,T> lerp;
|
|
Func<T,float> getValue;
|
|
Func<T,T,bool> validateLimits;
|
|
|
|
public bool cacheValues = true;
|
|
public float interpolationAmount = 1f;
|
|
|
|
Dictionary<T,float> _cachedValues = new Dictionary<T, float>();
|
|
|
|
public MinMaxSearch( Func<T,T,float,T> lerp, Func<T,float> getValue, Func<T,T,bool> validateLimits = null)
|
|
{
|
|
this.lerp = lerp;
|
|
this.getValue = getValue;
|
|
this.validateLimits = validateLimits;
|
|
}
|
|
|
|
public T Find( float searchValue, T low, T high, float treshold )
|
|
{
|
|
if ( validateLimits != null && ! validateLimits( low, high ) )
|
|
{
|
|
throw new Exception( "Limit validation failed" );
|
|
}
|
|
|
|
var tweened = GetTweened( searchValue, low, high );
|
|
var tweenedValue = GetValue( tweened );
|
|
var tweenedDifference = searchValue - tweenedValue;
|
|
|
|
Safe.While ( () => Mathf.Abs( tweenedDifference ) > treshold ,
|
|
()=>
|
|
{
|
|
if ( searchValue > tweenedValue )
|
|
{
|
|
low = tweened;
|
|
}
|
|
else
|
|
{
|
|
high = tweened;
|
|
}
|
|
|
|
if ( validateLimits != null && ! validateLimits( low, high ) )
|
|
{
|
|
throw new Exception( "Limit validation failed" );
|
|
}
|
|
|
|
tweened = GetTweened( searchValue, low, high );
|
|
tweenedValue = GetValue( tweened );
|
|
tweenedDifference = searchValue - tweenedValue;
|
|
}
|
|
);
|
|
|
|
return tweened;
|
|
}
|
|
|
|
public T GetTweened( float value, T low, T high )
|
|
{
|
|
var lowValue = getValue( low );
|
|
var highValue = getValue( high );
|
|
|
|
var position = MathX.Normalize( value, lowValue, highValue );
|
|
position = Mathf.Lerp( 0.5f, position, interpolationAmount );
|
|
|
|
return lerp( low, high, position );
|
|
}
|
|
|
|
float GetValue( T t )
|
|
{
|
|
if ( ! cacheValues )
|
|
{
|
|
return getValue( t );
|
|
}
|
|
|
|
if ( _cachedValues.ContainsKey( t ) )
|
|
{
|
|
return _cachedValues[ t ];
|
|
}
|
|
|
|
_cachedValues[ t ] = getValue( t );
|
|
|
|
return _cachedValues[ t ];
|
|
}
|
|
}
|
|
} |