UNPKG

ogl

Version:
80 lines (67 loc) 2.71 kB
import { Mesh } from '../core/Mesh.js'; import { Mat4 } from '../math/Mat4.js'; import { Texture } from '../core/Texture.js'; const tempMat4 = new Mat4(); const identity = new Mat4(); export class GLTFSkin extends Mesh { constructor(gl, { skeleton, geometry, program, mode = gl.TRIANGLES } = {}) { super(gl, { geometry, program, mode }); this.skeleton = skeleton; this.program = program; this.createBoneTexture(); this.animations = []; } createBoneTexture() { if (!this.skeleton.joints.length) return; const size = Math.max(4, Math.pow(2, Math.ceil(Math.log(Math.sqrt(this.skeleton.joints.length * 4)) / Math.LN2))); this.boneMatrices = new Float32Array(size * size * 4); this.boneTextureSize = size; this.boneTexture = new Texture(this.gl, { image: this.boneMatrices, generateMipmaps: false, type: this.gl.FLOAT, internalFormat: this.gl.renderer.isWebgl2 ? this.gl.RGBA32F : this.gl.RGBA, flipY: false, width: size, }); } // addAnimation(data) { // const animation = new Animation({ objects: this.bones, data }); // this.animations.push(animation); // return animation; // } // updateAnimations() { // // Calculate combined animation weight // let total = 0; // this.animations.forEach((animation) => (total += animation.weight)); // this.animations.forEach((animation, i) => { // // force first animation to set in order to reset frame // animation.update(total, i === 0); // }); // } updateUniforms() { // Update bone texture this.skeleton.joints.forEach((bone, i) => { // Find difference between current and bind pose tempMat4.multiply(bone.worldMatrix, bone.bindInverse); this.boneMatrices.set(tempMat4, i * 16); }); if (this.boneTexture) this.boneTexture.needsUpdate = true; } draw({ camera } = {}) { if (!this.program.uniforms.boneTexture) { Object.assign(this.program.uniforms, { boneTexture: { value: this.boneTexture }, boneTextureSize: { value: this.boneTextureSize }, }); } this.updateUniforms(); // Switch the world matrix with identity to ignore any transforms // on the mesh itself - only use skeleton's transforms const _worldMatrix = this.worldMatrix; this.worldMatrix = identity; super.draw({ camera }); // Switch back to leave identity untouched this.worldMatrix = _worldMatrix; } }