131 lines
2.3 KiB
C#
131 lines
2.3 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Text.RegularExpressions;
|
|
using System.Text;
|
|
using Godot;
|
|
|
|
namespace Rokojori
|
|
{
|
|
public class KeyFrameAnimation<T>
|
|
{
|
|
public List<KeyFrame<T>> keyFrames = new List<KeyFrame<T>>();
|
|
|
|
int _currentIndex = -1;
|
|
bool _sorted = false;
|
|
|
|
public void FlagUnsorted()
|
|
{
|
|
_sorted = false;
|
|
}
|
|
|
|
public void FlagSorted()
|
|
{
|
|
_sorted = true;
|
|
}
|
|
|
|
|
|
public void Sort()
|
|
{
|
|
if ( _sorted )
|
|
{
|
|
return;
|
|
}
|
|
|
|
keyFrames.Sort( ( a, b ) => Mathf.Sign( a.time - b.time ) );
|
|
|
|
_sorted = true;
|
|
}
|
|
|
|
public KeyFrame<T> GetKeyFrameAt( float time )
|
|
{
|
|
var index = GetKeyFrameIndexAt( time );
|
|
|
|
return index == -1 ? null : keyFrames[ index ];
|
|
}
|
|
|
|
public int GetKeyFrameIndexAt( float time )
|
|
{
|
|
if ( keyFrames.Count == 0 )
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
Sort();
|
|
|
|
for ( int i = 0; i < keyFrames.Count; i++ )
|
|
{
|
|
if ( keyFrames[ i ].time > time )
|
|
{
|
|
return Mathf.Max( 0, i - 1 );
|
|
}
|
|
}
|
|
|
|
if ( _sorted )
|
|
{
|
|
return keyFrames.Count - 1;
|
|
}
|
|
|
|
if ( IsKeyFrameAt( time, _currentIndex ) )
|
|
{
|
|
return _currentIndex;
|
|
}
|
|
|
|
_currentIndex = MathX.SafeIndex( _currentIndex, keyFrames );
|
|
|
|
var kf = keyFrames[ _currentIndex ];
|
|
|
|
if ( kf.time < time )
|
|
{
|
|
_currentIndex ++;
|
|
|
|
while ( _currentIndex < keyFrames.Count )
|
|
{
|
|
if ( IsKeyFrameAt( time, _currentIndex ) )
|
|
{
|
|
return _currentIndex;
|
|
}
|
|
|
|
_currentIndex ++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_currentIndex --;
|
|
|
|
while ( _currentIndex > -1 )
|
|
{
|
|
if ( IsKeyFrameAt( time, _currentIndex ) )
|
|
{
|
|
return _currentIndex;
|
|
}
|
|
|
|
_currentIndex --;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
bool IsKeyFrameAt( float time, int index )
|
|
{
|
|
if ( index < 0 || index >= keyFrames.Count -1 )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var i = keyFrames[ index ];
|
|
|
|
if ( i.time < time && index == keyFrames.Count - 1 )
|
|
{
|
|
return true;
|
|
}
|
|
|
|
var n = keyFrames[ index + 1 ];
|
|
|
|
return i.time < time && time < n.time;
|
|
|
|
}
|
|
|
|
}
|
|
} |