UNPKG

nanogl-gltf

Version:
50 lines (49 loc) 2.03 kB
import { mat4 } from 'gl-matrix'; import GltfTypes from '../types/GltfTypes'; const M4 = mat4.create(); /** * The Skin element contains the joints nodes and inverse bind matrices used to animate a mesh. */ export default class Skin { constructor() { this.gltftype = GltfTypes.SKIN; } /** * Parse the Skin data. * * Is async as it needs to wait for all the skeleton root and joints Nodes, * and the possible inverseBindMatrices Accessor to be created. * @param gltfLoader GLTFLoader to use * @param data Data to parse */ async parse(gltfLoader, data) { const jointPromises = data.joints.map(idx => gltfLoader.getElement(GltfTypes.NODE, idx)); this.joints = await Promise.all(jointPromises); this.inverseBindMatrices = this.joints.map(mat4.create); if (data.inverseBindMatrices !== undefined) { const ibmAccessor = await gltfLoader.getElement(GltfTypes.ACCESSOR, data.inverseBindMatrices); this.inverseBindMatrices.forEach((m, i) => ibmAccessor.getValue(m, i)); } if (data.skeleton !== undefined) { this.skeletonRoot = await gltfLoader.getElement(GltfTypes.NODE, data.skeleton); } } /** * Compute the joints matrices, used to animate the skin. * @param skinnedNode Skinned node to compute the joints matrices for * @param jointMatrices Joints matrices to compute */ computeJoints(skinnedNode, jointMatrices) { if (jointMatrices.length !== this.joints.length) { throw new Error("Skin.computeJoints(), jointMatrices size must match joints size"); } mat4.invert(M4, skinnedNode._wmatrix); for (let i = 0; i < this.joints.length; i++) { const joint = this.joints[i]; const ibm = this.inverseBindMatrices[i]; const jointMatrix = jointMatrices[i]; mat4.mul(jointMatrix, joint._wmatrix, ibm); mat4.mul(jointMatrix, M4, jointMatrix); } } }