UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

85 lines (66 loc) 3.03 kB
/** * * @param {number[]|Float32Array} destination * @param {number} destination_offset * @param {number[]|Float32Array} positions * @param {number} vertex_count * @param {number[]|Float32Array} skin_weights_array * @param {number[]|Uint32Array} skin_indices_array * @param {number[]|Float32Array} bone_matrices 4x3 transform matrices * @param {number[]|Float32Array} m4_bind * @param {number[]|Float32Array} m4_bind_inv * @param {number} [bones_per_vertex] */ export function mesh_apply_skeletal_vertex_skinning( destination, destination_offset, positions, vertex_count, skin_weights_array, skin_indices_array, bone_matrices, m4_bind, m4_bind_inv, bones_per_vertex = 4 ) { let index, i, x, y, z; for (index = 0; index < vertex_count; index++) { const index3 = index * 3; //read vertex position const px = positions[index3]; const py = positions[index3 + 1]; const pz = positions[index3 + 2]; //apply bind matrix transform to vertex const bx = m4_bind[0] * px + m4_bind[4] * py + m4_bind[8] * pz + m4_bind[12]; const by = m4_bind[1] * px + m4_bind[5] * py + m4_bind[9] * pz + m4_bind[13]; const bz = m4_bind[2] * px + m4_bind[6] * py + m4_bind[10] * pz + m4_bind[14]; x = 0; y = 0; z = 0; for (i = 0; i < bones_per_vertex; i++) { const skin_index = index * bones_per_vertex + i; const skin_weight = skin_weights_array[skin_index]; if (skin_weight !== 0) { const boneIndex = skin_indices_array[skin_index]; const bdIndex = boneIndex * 12; const sx = bone_matrices[bdIndex] * bx + bone_matrices[bdIndex + 1] * by + bone_matrices[bdIndex + 2] * bz + bone_matrices[bdIndex + 3]; const sy = bone_matrices[bdIndex + 4] * bx + bone_matrices[bdIndex + 5] * by + bone_matrices[bdIndex + 6] * bz + bone_matrices[bdIndex + 7]; const sz = bone_matrices[bdIndex + 8] * bx + bone_matrices[bdIndex + 9] * by + bone_matrices[bdIndex + 10] * bz + bone_matrices[bdIndex + 11]; const tx = sx * skin_weight; const ty = sy * skin_weight; const tz = sz * skin_weight; x += tx; y += ty; z += tz; } } //apply inverse bind matrix const wx = m4_bind_inv[0] * x + m4_bind_inv[4] * y + m4_bind_inv[8] * z + m4_bind_inv[12]; const wy = m4_bind_inv[1] * x + m4_bind_inv[5] * y + m4_bind_inv[9] * z + m4_bind_inv[13]; const wz = m4_bind_inv[2] * x + m4_bind_inv[6] * y + m4_bind_inv[10] * z + m4_bind_inv[14]; const destination_address = destination_offset + index3; destination[destination_address] = wx; destination[destination_address + 1] = wy; destination[destination_address + 2] = wz; } }