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;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 |