@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
55 lines (40 loc) • 2.04 kB
JavaScript
import { m4_multiply } from "../../../../core/geom/3d/mat4/m4_multiply.js";
import { mat4x4_transpose_copy_to_mat4x3 } from "../../../../core/math/matrix/mat4x4_transpose_copy_to_mat4x3.js";
import { mesh_apply_skeletal_vertex_skinning } from "./mesh_apply_skeletal_vertex_skinning.js";
/**
* NOTE: the method is completely inlined for better performance. 0 function calls within the skinning loop
* @param {Float32Array} destination Skinned vertex positions
* @param {SkinnedMesh} mesh
* @param {number} [destination_offset=0]
*/
export function computeSkinnedMeshVertices(
destination,
mesh,
destination_offset = 0
) {
const geometry = mesh.geometry;
const skeleton = mesh.skeleton;
const tempMatrix = new Float32Array(16);
const attributes = geometry.attributes;
const positions = attributes.position.array;
const skin_indices_array = attributes.skinIndex.array;
const skin_weights_array = attributes.skinWeight.array;
const vertex_count = attributes.position.count;
const bones = skeleton.bones;
const boneCount = bones.length;
//pre-build transform matrices for bones
const boneMatrixData = new Float32Array(boneCount * 12);
for (let boneIndex = 0; boneIndex < boneCount; boneIndex++) {
const targetIndex = boneIndex * 12;
m4_multiply(tempMatrix, bones[boneIndex].matrixWorld.elements, skeleton.boneInverses[boneIndex].elements);
// write matrix data in transposed form, to conform to access order when applied to Vector3 transformation
mat4x4_transpose_copy_to_mat4x3(
boneMatrixData, targetIndex,
tempMatrix, 0
);
}
const m4_bind = mesh.bindMatrix.elements;
// inverse of bind matrix
const m4_bind_inv = mesh.bindMatrixInverse.elements;
mesh_apply_skeletal_vertex_skinning(destination, destination_offset, positions, vertex_count, skin_weights_array, skin_indices_array, boneMatrixData, m4_bind, m4_bind_inv);
}