import { vec3 } from 'gl-matrix' ; import { Vec3Util } from '.' ; class CurveSample { _totalLen = 0 ; _sampleCnt = 0 ; _aryLen : Array < number > ; _aryInc : Array < number > ; _aryPos : Array < vec3 > ; constructor ( cnt = 0 ) { if ( cnt == 0 ) { this . _aryLen = [ ] ; this . _aryInc = [ ] ; this . _aryPos = [ ] ; } else { this . _sampleCnt = cnt ; this . _aryLen = new Array ( cnt ) ; this . _aryLen . fill ( 0 ) ; this . _aryInc = this . _aryLen . slice ( 0 ) ; this . _aryPos = this . _aryLen . map ( ( ) => [ 0 , 0 , 0 ] ) ; } } add ( pnt ) { if ( this . _sampleCnt > 0 ) { let inc = Vec3Util . len ( pnt , this . _aryPos [ this . _sampleCnt - 1 ] ) ; this . _totalLen += inc ; this . _aryLen . push ( this . _totalLen ) ; this . _aryInc . push ( inc ) ; } else { this . _aryLen . push ( 0 ) ; this . _aryInc . push ( 0 ) ; } this . _aryPos . push ( Array . from ( pnt ) as vec3 ) ; this . _sampleCnt ++ ; } set ( i , pnt ) { vec3 . copy ( this . _aryPos [ i ] , pnt ) ; } updateLengths ( ) { let inc ; this . _totalLen = 0 ; for ( let i = 1 ; i < this . _sampleCnt ; i ++ ) { inc = Vec3Util . len ( this . _aryPos [ i ] , this . _aryPos [ i - 1 ] ) ; this . _totalLen += inc ; this . _aryLen [ i ] = this . _totalLen ; this . _aryInc [ i ] = inc ; } } atLength ( len , out ? ) { const alen = this . _aryLen ; const ainc = this . _aryInc ; out ??= [ 0 , 0 , 0 ] ; if ( len <= 0 ) vec3 . copy ( out , this . _aryPos [ 0 ] ) ; else if ( len >= this . _totalLen - 0.001 ) vec3 . copy ( out , this . _aryPos [ this . _sampleCnt - 1 ] ) ; else { for ( let i = this . _sampleCnt - 1 ; i >= 0 ; i -- ) { if ( alen [ i ] < len ) { const t = ( len - alen [ i ] ) / ainc [ i + 1 ] ; vec3 . lerp ( out , this . _aryPos [ i ] , this . _aryPos [ i + 1 ] , t ) ; return out ; } } } return out ; } } export default CurveSample ;