import type Pose from '../../armature/Pose' ; import type { IKChain } from "../rigs/IKChain" ; import type { IKData } from '..' ; import type { ISolver } from './support/ISolver' ; import { Transform } from '../../maths' ; import { vec3 } from 'gl-matrix' ; import SwingTwistSolver from "./SwingTwistSolver" ; class HipSolver implements ISolver { isAbs : boolean = true ; position : vec3 = [ 0 , 0 , 0 ] ; bindHeight : number = 0 ; _swingTwist = new SwingTwistSolver ( ) ; initData ( pose ? , chain ? ) { if ( pose && chain ) { const b = pose . bones [ chain . links [ 0 ] . idx ] ; this . setMovePos ( b . world . pos , true ) ; this . _swingTwist . initData ( pose , chain ) ; } return this ; } setTargetDir ( e , pole ? ) { this . _swingTwist . setTargetDir ( e , pole ) ; return this ; } setTargetPos ( v , pole ? ) { this . _swingTwist . setTargetPos ( v , pole ) ; return this ; } setTargetPole ( v ) { this . _swingTwist . setTargetPole ( v ) ; return this ; } setMovePos ( pos , isAbs = true , bindHeight = 0 ) { this . position [ 0 ] = pos [ 0 ] ; this . position [ 1 ] = pos [ 1 ] ; this . position [ 2 ] = pos [ 2 ] ; this . isAbs = isAbs ; this . bindHeight = bindHeight ; return this ; } resolve ( chain , pose , debug ? ) { const hipPos = [ 0 , 0 , 0 ] ; const pt = new Transform ( ) ; const ptInv = new Transform ( ) ; const lnk = chain . first ( ) ; if ( lnk . pidx == - 1 ) pt . copy ( pose . offset ) ; else pose . getWorldTransform ( lnk . pidx , pt ) ; ptInv . fromInvert ( pt ) ; if ( this . isAbs ) { vec3 . copy ( hipPos , this . position ) ; } else { const ct = new Transform ( ) ; ct . fromMul ( pt , lnk . bind ) ; if ( this . bindHeight == 0 ) { vec3 . add ( hipPos , ct . pos , this . position ) ; } else { vec3 . scaleAndAdd ( hipPos , ct . pos , this . position , Math . abs ( ct . pos [ 1 ] / this . bindHeight ) ) ; } } ptInv . transformVec3 ( hipPos ) ; pose . setLocalPos ( lnk . idx , hipPos ) ; this . _swingTwist . resolve ( chain , pose , debug ) ; } ikDataFromPose ( chain , pose , out ) { const v = [ 0 , 0 , 0 ] ; const lnk = chain . first ( ) ; const b = pose . bones [ lnk . idx ] ; const tran = new Transform ( ) ; if ( b . pidx == - 1 ) tran . fromMul ( pose . offset , lnk . bind ) ; else pose . getWorldTransform ( lnk . pidx , tran ) . mul ( lnk . bind ) ; vec3 . sub ( v , b . world . pos , tran . pos ) ; out . isAbsolute = false ; out . bindHeight = tran . pos [ 1 ] ; vec3 . copy ( out . pos , v ) ; vec3 . transformQuat ( v , lnk . effectorDir , b . world . rot ) ; vec3 . normalize ( out . effectorDir , v ) ; vec3 . transformQuat ( v , lnk . poleDir , b . world . rot ) ; vec3 . normalize ( out . poleDir , v ) ; } } export default HipSolver ;