import type { ISkin , TTextureInfo } from './ISkin.js' ; import type Armature from '../Armature' ; import type Pose from '../Pose' ; import { mat4 } from 'gl-matrix' ; import Mat4Util from '../../maths/Mat4Util' ; import Bone from '../Bone.js' ; const COMP_LEN = 16 ; const BYTE_LEN = COMP_LEN * 4 ; class SkinMTX implements ISkin { bind ! : mat4 [ ] ; world ! : mat4 [ ] ; offsetBuffer ! : Float32Array ; init ( arm ) { const mat4Identity = mat4 . create ( ) ; const bCnt = arm . bones . length ; const world = new Array ( bCnt ) ; const bind = new Array ( bCnt ) ; this . offsetBuffer = new Float32Array ( 16 * bCnt ) ; for ( let i = 0 ; i < bCnt ; i ++ ) { world [ i ] = mat4 . create ( ) ; bind [ i ] = mat4 . create ( ) ; } let b , l , m ; for ( let i = 0 ; i < bCnt ; i ++ ) { b = arm . bones [ i ] ; l = b . local ; m = world [ i ] ; mat4 . fromRotationTranslationScale ( m , l . rot , l . pos , l . scl ) ; if ( b . pidx != - 1 ) mat4 . mul ( m , world [ b . pidx ] , m ) ; mat4 . invert ( bind [ i ] , m ) ; Mat4Util . toBuf ( mat4Identity , this . offsetBuffer , i * 16 ) ; } this . bind = bind ; this . world = world ; return this ; } updateFromPose ( pose ) { const offset = mat4 . create ( ) ; mat4 . fromRotationTranslationScale ( offset , pose . offset . rot , pose . offset . pos , pose . offset . scl ) ; const bOffset = mat4 . create ( ) ; let b ; let m ; let i ; for ( i = 0 ; i < pose . bones . length ; i ++ ) { b = pose . bones [ i ] ; m = this . world [ i ] ; mat4 . fromRotationTranslationScale ( m , b . local . rot , b . local . pos , b . local . scl ) ; if ( b . pidx != - 1 ) mat4 . mul ( m , this . world [ b . pidx ] , m ) ; else mat4 . mul ( m , offset , m ) ; mat4 . mul ( bOffset , m , this . bind [ i ] ) ; Mat4Util . toBuf ( bOffset , this . offsetBuffer , i * 16 ) ; } return this ; } getOffsets ( ) { return [ this . offsetBuffer ] ; } getTextureInfo ( frameCount ) { const boneCount = this . bind . length ; const strideFloatLength = COMP_LEN ; const strideByteLength = BYTE_LEN ; const pixelsPerStride = COMP_LEN / 4 ; const floatRowSize = COMP_LEN * frameCount ; const bufferFloatSize = floatRowSize * boneCount ; const bufferByteSize = bufferFloatSize * 4 ; const pixelWidth = pixelsPerStride * frameCount ; const pixelHeight = boneCount ; const o = { boneCount , strideFloatLength , strideByteLength , pixelsPerStride , floatRowSize , bufferFloatSize , bufferByteSize , pixelWidth , pixelHeight , } ; return o ; } } export default SkinMTX ;