import type { ISkin , TTextureInfo } from './ISkin.js' ; import type Armature from '../Armature' ; import type Pose from '../Pose' ; import { quat2 } from 'gl-matrix' ; import Vec4Util from '../../maths/Vec4Util' ; import Vec3Util from '../../maths/Vec3Util' ; import Transform from '../../maths/Transform' ; import Bone from '../Bone.js' ; const COMP_LEN = 12 ; const BYTE_LEN = COMP_LEN * 4 ; class SkinDQT implements ISkin { bind ! : Transform [ ] ; world ! : Transform [ ] ; offsetQBuffer ! : Float32Array ; offsetPBuffer ! : Float32Array ; offsetSBuffer ! : Float32Array ; init ( arm ) { const bCnt = arm . bones . length ; const world = new Array ( bCnt ) ; const bind = new Array ( bCnt ) ; this . offsetQBuffer = new Float32Array ( 4 * bCnt ) ; this . offsetPBuffer = new Float32Array ( 4 * bCnt ) ; this . offsetSBuffer = new Float32Array ( 3 * bCnt ) ; for ( let i = 0 ; i < bCnt ; i ++ ) { world [ i ] = new Transform ( ) ; bind [ i ] = new Transform ( ) ; } let b ; let t ; for ( let i = 0 ; i < bCnt ; i ++ ) { b = arm . bones [ i ] ; t = world [ i ] ; t . copy ( b . local ) ; if ( b . pidx != - 1 ) t . pmul ( world [ b . pidx ] ) ; bind [ i ] . fromInvert ( t ) ; Vec4Util . toBuf ( [ 0 , 0 , 0 , 1 ] , this . offsetQBuffer , i * 4 ) ; Vec4Util . toBuf ( [ 0 , 0 , 0 , 0 ] , this . offsetPBuffer , i * 4 ) ; Vec3Util . toBuf ( [ 1 , 1 , 1 ] , this . offsetSBuffer , i * 3 ) ; } this . bind = bind ; this . world = world ; return this ; } updateFromPose ( pose ) { const offset = pose . offset ; const bOffset = new Transform ( ) ; const dq = quat2 . create ( ) ; let b ; let ws ; let i ; let ii ; let si ; for ( i = 0 ; i < pose . bones . length ; i ++ ) { b = pose . bones [ i ] ; ws = this . world [ i ] ; if ( b . pidx != - 1 ) ws . fromMul ( this . world [ b . pidx ] , b . local ) ; else ws . fromMul ( offset , b . local ) ; bOffset . fromMul ( ws , this . bind [ i ] ) ; quat2 . fromRotationTranslation ( dq , bOffset . rot , bOffset . pos ) ; ii = i * 4 ; si = i * 3 ; this . offsetQBuffer [ ii + 0 ] = dq [ 0 ] ; this . offsetQBuffer [ ii + 1 ] = dq [ 1 ] ; this . offsetQBuffer [ ii + 2 ] = dq [ 2 ] ; this . offsetQBuffer [ ii + 3 ] = dq [ 3 ] ; this . offsetPBuffer [ ii + 0 ] = dq [ 4 ] ; this . offsetPBuffer [ ii + 1 ] = dq [ 5 ] ; this . offsetPBuffer [ ii + 2 ] = dq [ 6 ] ; this . offsetPBuffer [ ii + 3 ] = dq [ 7 ] ; this . offsetSBuffer [ si + 0 ] = bOffset . scl [ 0 ] ; this . offsetSBuffer [ si + 1 ] = bOffset . scl [ 1 ] ; this . offsetSBuffer [ si + 2 ] = bOffset . scl [ 2 ] ; } return this ; } getOffsets ( ) { return [ this . offsetQBuffer , this . offsetPBuffer , this . offsetSBuffer ] ; } getTextureInfo ( frameCount ) { const boneCount = this . bind . length ; const strideByteLength = BYTE_LEN ; const strideFloatLength = COMP_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 , strideByteLength , strideFloatLength , pixelsPerStride , floatRowSize , bufferFloatSize , bufferByteSize , pixelWidth , pixelHeight , } ; return o ; } } export default SkinDQT ;