UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

102 lines (77 loc) 2.84 kB
import { assert } from "../../../../../core/assert.js"; import { string_compute_common_prefix } from "../../../../../core/primitives/strings/string_compute_common_prefix.js"; import { string_compute_similarity } from "../../../../../core/primitives/strings/string_compute_similarity.js"; import { HumanoidBoneType } from "./HumanoidBoneType.js"; /** * * @param {{distance:number}} a * @param {{distance:number}} b * @returns {number} */ function byDistance(a, b) { return b.distance - a.distance; } export class BoneMapping { constructor() { this.mapping = []; } /** * * @param {string[]} names */ build(names) { //strip common prefix const commonPrefix = string_compute_common_prefix(names); const commonPrefixLength = commonPrefix.length; const conditionedNames = names.map(function (name) { return name.substring(commonPrefixLength); }); const boneValues = Object.values(HumanoidBoneType); //compute probability distribution for each name to a known bone const matches = []; boneValues.forEach(function (boneName, boneIndex) { conditionedNames.forEach(function (name, inputIndex) { const distance = string_compute_similarity(name, boneName); const match = { boneIndex, inputIndex, distance }; matches.push(match); }); }); //sort distribution according to distance matches.sort(byDistance); //assign mapping let numMatches = matches.length; while (numMatches > 0) { const match = matches.pop(); numMatches--; const boneIndex = match.boneIndex; const inputIndex = match.inputIndex; const boneValue = boneValues[boneIndex]; this.mapping[inputIndex] = boneValue; //remove all references to this bone index and input for (let i = 0; i < numMatches; i++) { const match = matches[i]; if (match.boneIndex === boneIndex || match.inputIndex === inputIndex) { matches.splice(i, 1); numMatches--; i--; } } } } /** * @param {Bone[]} bones */ apply(bones) { assert.ok(Array.isArray(bones), 'bones argument must be an array'); const numBones = bones.length; for (let i = 0; i < numBones; i++) { const bone = bones[i]; const boneType = this.mapping[i]; bone.boneType = boneType; } } }