import type { ISkin } from './skins/ISkin.js' ; import { vec3 , quat } from 'gl-matrix' ; import Transform from '../maths/Transform' ; import Vec3Util from '../maths/Vec3Util' ; import Bone from './Bone' ; import Pose from './Pose' ; class Armature { names : Map < string , number > = new Map ( ) ; bones : Array < Bone > = [ ] ; skin ? : ISkin ; offset : Transform = new Transform ( ) ; addBone ( name , pidx ? , rot ? , pos ? , scl ? ) { const idx = this . bones . length ; const bone = new Bone ( name , idx ) ; this . bones . push ( bone ) ; this . names . set ( name , idx ) ; if ( pos || rot || scl ) bone . setLocal ( rot , pos , scl ) ; if ( pidx != null && pidx != undefined && pidx != - 1 ) bone . pidx = pidx ; return bone ; } bind ( skin ? , defaultBoneLen = 1.0 ) { this . updateWorld ( ) ; this . updateBoneLengths ( defaultBoneLen ) ; if ( skin ) this . skin = new skin ( ) . init ( this ) ; return this ; } newPose ( doWorldUpdate = false ) { const p = new Pose ( this ) ; return ( doWorldUpdate ) ? p . updateWorld ( ) : p ; } getBone ( bName ) { const idx = this . names . get ( bName ) ; if ( idx == undefined ) return null ; return this . bones [ idx ] ; } getSkinOffsets ( ) { return ( this . skin ) ? this . skin . getOffsets ( ) : null ; } updateSkinFromPose ( pose ) { if ( this . skin ) { this . skin . updateFromPose ( pose ) ; return this . skin . getOffsets ( ) ; } return null ; } updateWorld ( ) { const bCnt = this . bones . length ; let b ; for ( let i = 0 ; i < bCnt ; i ++ ) { b = this . bones [ i ] ; if ( b . pidx != - 1 ) b . world . fromMul ( this . bones [ b . pidx ] . world , b . local ) ; else b . world . copy ( b . local ) ; } return this ; } updateBoneLengths ( defaultBoneLen = 0 ) { const bCnt = this . bones . length ; let b ; let p ; for ( let i = bCnt - 1 ; i >= 0 ; i -- ) { b = this . bones [ i ] ; if ( b . pidx == - 1 ) continue ; p = this . bones [ b . pidx ] ; p . len = Vec3Util . len ( p . world . pos , b . world . pos ) ; } if ( defaultBoneLen != 0 ) { for ( let i = 0 ; i < bCnt ; i ++ ) { b = this . bones [ i ] ; if ( b . len == 0 ) b . len = defaultBoneLen ; } } return this ; } } export default Armature ;