import type { ITrack } from './tracks/types' ; import type Pose from '../armature/Pose' ; import type Clip from './Clip' ; import Maths from '../maths/Maths' ; /** Set of information to pass to Tracks for when animating a character. */ class FrameInfo { kt0 : number = 0 ; kt1 : number = 0 ; k0 : number = - 1 ; k1 : number = - 1 ; t : number = 0 ; ti : number = 0 ; } /** Basic Animator for Armature */ class Animator { frameInfo : Array < FrameInfo > = [ ] ; clock : number = 0 ; clip ! : Clip ; inPlace = false ; setClip ( c ) { this . clip = c ; return this ; } /** Move Animation to the next possible frame. */ update ( deltaTime ) { this . clock = ( this . clock + deltaTime ) % this . clip . duration ; this . _computeFrameInfo ( ) ; return this ; } applyPose ( pose ) { if ( ! this . clip ) return this ; let t ; for ( t of this . clip . tracks ) { t . apply ( pose , this . frameInfo [ t . timeStampIndex ] ) ; } if ( this . inPlace ) { const bPos = pose . bones [ 0 ] . local . pos ; bPos [ 1 ] = 0 ; } return this ; } /** Set Animator on a specific frame */ atKey ( n ) { if ( ! this . clip ) return this ; if ( n < 0 ) n = 0 ; this . _genFrameInfo ( ) ; const aryTs = this . clip . timeStamps ; const aryFi = this . frameInfo ; let ts ; let fi ; let tsLen ; for ( let i = 0 ; i < aryTs . length ; i ++ ) { ts = aryTs [ i ] ; fi = aryFi [ i ] ; tsLen = ts . length - 1 ; fi . t = 1 ; fi . ti = 0 ; fi . k0 = ( n <= tsLen ) ? n : tsLen ; fi . k1 = fi . k0 ; fi . kt0 = fi . k0 ; fi . kt1 = fi . k0 ; } return this ; } /** Make sure we have enough frame info objects to handle all the timestamps of the clip  */ _genFrameInfo ( ) { const aryFi = this . frameInfo ; const aryTs = this . clip . timeStamps ; if ( aryFi . length < aryTs . length ) { for ( let i = aryFi . length ; i < aryTs . length ; i ++ ) aryFi . push ( new FrameInfo ) ; } } _computeFrameInfo ( ) { if ( ! this . clip ) return ; this . _genFrameInfo ( ) ; const aryFi = this . frameInfo ; const aryTs = this . clip . timeStamps ; const time = this . clock ; let ts ; let fi ; let tLen ; for ( let i = 0 ; i < aryTs . length ; i ++ ) { ts = aryTs [ i ] ; fi = aryFi [ i ] ; tLen = ts . length ; if ( tLen == 0 ) { fi . t = 1 ; fi . ti = 0 ; fi . k0 = 0 ; fi . k1 = 0 ; fi . kt0 = 0 ; fi . kt1 = 0 ; continue ; } if ( fi . k0 != - 1 && time >= ts [ fi . k0 ] && time <= ts [ fi . k1 ] ) { } else { let imin = 0 , mi = 0 , imax = ts . length - 1 ; while ( imin < imax ) { mi = ( imin + imax ) >>> 1 ; if ( time < ts [ mi ] ) imax = mi ; else imin = mi + 1 ; } if ( imax <= 0 ) { fi . k0 = 0 ; fi . k1 = 1 ; } else { fi . k0 = imax - 1 ; fi . k1 = imax ; } fi . kt0 = Maths . mod ( fi . k0 - 1 , tLen ) ; fi . kt1 = Maths . mod ( fi . k1 + 1 , tLen ) ; } fi . t = ( time - ts [ fi . k0 ] ) / ( ts [ fi . k1 ] - ts [ fi . k0 ] ) ; fi . ti = 1 - fi . t ; } } } export default Animator ; export { FrameInfo } ;