@animech-public/playcanvas
Version:
PlayCanvas WebGL game engine
2 lines (1 loc) • 2.12 kB
JavaScript
import{math as t}from"../core/math/math.js";import{Mat4 as e}from"../core/math/mat4.js";import{PIXELFORMAT_RGBA32F as s,FILTER_NEAREST as i,TEXTURELOCK_READ as o}from"../platform/graphics/constants.js";import{Texture as n}from"../platform/graphics/texture.js";const r=new e;class h{constructor(t){this.bones=void 0,this.boneTextureSize=void 0,this._dirty=!0,this._rootBone=null,this._skinUpdateIndex=-1,this._updateBeforeCull=!0,t&&this.initSkin(t)}set rootBone(t){this._rootBone=t}get rootBone(){return this._rootBone}init(e,r){if(e.supportsBoneTextures){const h=3*r;let a=Math.ceil(Math.sqrt(h));a=t.roundUp(a,3);const l=Math.ceil(h/a);this.boneTexture=new n(e,{width:a,height:l,format:s,mipmaps:!1,minFilter:i,magFilter:i,name:"skin"}),this.boneTextureSize=[a,l,1/a,1/l],this.matrixPalette=this.boneTexture.lock({mode:o}),this.boneTexture.unlock()}else this.matrixPalette=new Float32Array(12*r)}destroy(){this.boneTexture&&(this.boneTexture.destroy(),this.boneTexture=null)}resolve(t,e){this.rootBone=t;const s=this.skin,i=[];for(let o=0;o<s.boneNames.length;o++){const n=s.boneNames[o];let r=t.findByName(n);r||(r=e),i.push(r)}this.bones=i}initSkin(t){this.skin=t,this.bones=[];const s=t.inverseBindPose.length;this.init(t.device,s),this.matrices=[];for(let t=0;t<s;t++)this.matrices[t]=new e}uploadBones(t){t.supportsBoneTextures&&(this.boneTexture.lock(),this.boneTexture.unlock())}_updateMatrices(t,e){if(this._skinUpdateIndex!==e){this._skinUpdateIndex=e,r.copy(t.getWorldTransform()).invert();for(let t=this.bones.length-1;t>=0;t--)this.matrices[t].mulAffine2(r,this.bones[t].getWorldTransform()),this.matrices[t].mulAffine2(this.matrices[t],this.skin.inverseBindPose[t])}}updateMatrices(t,e){this._updateBeforeCull&&this._updateMatrices(t,e)}updateMatrixPalette(t,e){this._updateMatrices(t,e);const s=this.matrixPalette,i=this.bones.length;for(let t=0;t<i;t++){const e=this.matrices[t].data,i=12*t;s[i]=e[0],s[i+1]=e[4],s[i+2]=e[8],s[i+3]=e[12],s[i+4]=e[1],s[i+5]=e[5],s[i+6]=e[9],s[i+7]=e[13],s[i+8]=e[2],s[i+9]=e[6],s[i+10]=e[10],s[i+11]=e[14]}this.uploadBones(this.skin.device)}}export{h as SkinInstance};