import type Bone from '../armature/Bone' ; import type Pose from '../armature/Pose' ; import type { ISpringType } from './index' ; import type SpringChain from './SpringChain' ; import { vec3 , quat } from 'gl-matrix' ; import Transform from '../maths/Transform' ; import SpringItem from './SpringItem' ; import QuatUtil from '../maths/QuatUtil' ; class SpringRot implements ISpringType { setRestPose ( chain , pose ) { let si ; let b ; let tail = vec3 . create ( ) ; for ( si of chain . items ) { b = pose . bones [ si . index ] ; vec3 . set ( tail , 0 , b . len , 0 ) ; b . world . transformVec3 ( tail ) ; si . spring . reset ( tail ) ; si . bind . copy ( b . local ) ; } } updatePose ( chain , pose , dt ) { let si ; let b ; let tail = vec3 . create ( ) ; let pTran = new Transform ( ) ; let cTran = new Transform ( ) ; let va = vec3 . create ( ) ; let vb = vec3 . create ( ) ; let rot = quat . create ( ) ; si = chain . items [ 0 ] ; b = pose . bones [ si . index ] ; if ( b . pidx != - 1 ) pTran . copy ( pose . bones [ b . pidx ] . world ) ; else pTran . copy ( pose . offset ) ; for ( si of chain . items ) { b = pose . bones [ si . index ] ; cTran . fromMul ( pTran , si . bind ) ; vec3 . set ( tail , 0 , b . len , 0 ) ; cTran . transformVec3 ( tail ) ; si . spring . setTarget ( tail ) . update ( dt ) ; vec3 . sub ( va , tail , cTran . pos ) ; vec3 . normalize ( va , va ) ; vec3 . sub ( vb , si . spring . val , cTran . pos ) ; vec3 . normalize ( vb , vb ) ; quat . rotationTo ( rot , va , vb ) ; QuatUtil . dotNegate ( rot , rot , cTran . rot ) ; quat . mul ( rot , rot , cTran . rot ) ; QuatUtil . pmulInvert ( rot , rot , pTran . rot ) ; quat . copy ( b . local . rot , rot ) ; pTran . mul ( rot , si . bind . pos , si . bind . scl ) ; } } } export default SpringRot ;