using System.Collections; using System.Collections.Generic; using System.Text.RegularExpressions; using System.Text; using Godot; namespace Rokojori { public class KeyFrameAnimation { public List> keyFrames = new List>(); 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 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; } } }