UNPKG

three-stdlib

Version:

stand-alone library of threejs examples

1 lines 14.4 kB
{"version":3,"file":"SkeletonUtils.cjs","sources":["../../src/utils/SkeletonUtils.js"],"sourcesContent":["import {\n AnimationClip,\n AnimationMixer,\n Matrix4,\n Quaternion,\n QuaternionKeyframeTrack,\n SkeletonHelper,\n Vector3,\n VectorKeyframeTrack,\n} from 'three'\n\nfunction retarget(target, source, options = {}) {\n const pos = new Vector3(),\n quat = new Quaternion(),\n scale = new Vector3(),\n bindBoneMatrix = new Matrix4(),\n relativeMatrix = new Matrix4(),\n globalMatrix = new Matrix4()\n\n options.preserveMatrix = options.preserveMatrix !== undefined ? options.preserveMatrix : true\n options.preservePosition = options.preservePosition !== undefined ? options.preservePosition : true\n options.preserveHipPosition = options.preserveHipPosition !== undefined ? options.preserveHipPosition : false\n options.useTargetMatrix = options.useTargetMatrix !== undefined ? options.useTargetMatrix : false\n options.hip = options.hip !== undefined ? options.hip : 'hip'\n options.names = options.names || {}\n\n const sourceBones = source.isObject3D ? source.skeleton.bones : getBones(source),\n bones = target.isObject3D ? target.skeleton.bones : getBones(target)\n\n let bindBones, bone, name, boneTo, bonesPosition\n\n // reset bones\n\n if (target.isObject3D) {\n target.skeleton.pose()\n } else {\n options.useTargetMatrix = true\n options.preserveMatrix = false\n }\n\n if (options.preservePosition) {\n bonesPosition = []\n\n for (let i = 0; i < bones.length; i++) {\n bonesPosition.push(bones[i].position.clone())\n }\n }\n\n if (options.preserveMatrix) {\n // reset matrix\n\n target.updateMatrixWorld()\n\n target.matrixWorld.identity()\n\n // reset children matrix\n\n for (let i = 0; i < target.children.length; ++i) {\n target.children[i].updateMatrixWorld(true)\n }\n }\n\n if (options.offsets) {\n bindBones = []\n\n for (let i = 0; i < bones.length; ++i) {\n bone = bones[i]\n name = options.names[bone.name] || bone.name\n\n if (options.offsets[name]) {\n bone.matrix.multiply(options.offsets[name])\n\n bone.matrix.decompose(bone.position, bone.quaternion, bone.scale)\n\n bone.updateMatrixWorld()\n }\n\n bindBones.push(bone.matrixWorld.clone())\n }\n }\n\n for (let i = 0; i < bones.length; ++i) {\n bone = bones[i]\n name = options.names[bone.name] || bone.name\n\n boneTo = getBoneByName(name, sourceBones)\n\n globalMatrix.copy(bone.matrixWorld)\n\n if (boneTo) {\n boneTo.updateMatrixWorld()\n\n if (options.useTargetMatrix) {\n relativeMatrix.copy(boneTo.matrixWorld)\n } else {\n relativeMatrix.copy(target.matrixWorld).invert()\n relativeMatrix.multiply(boneTo.matrixWorld)\n }\n\n // ignore scale to extract rotation\n\n scale.setFromMatrixScale(relativeMatrix)\n relativeMatrix.scale(scale.set(1 / scale.x, 1 / scale.y, 1 / scale.z))\n\n // apply to global matrix\n\n globalMatrix.makeRotationFromQuaternion(quat.setFromRotationMatrix(relativeMatrix))\n\n if (target.isObject3D) {\n const boneIndex = bones.indexOf(bone),\n wBindMatrix = bindBones\n ? bindBones[boneIndex]\n : bindBoneMatrix.copy(target.skeleton.boneInverses[boneIndex]).invert()\n\n globalMatrix.multiply(wBindMatrix)\n }\n\n globalMatrix.copyPosition(relativeMatrix)\n }\n\n if (bone.parent && bone.parent.isBone) {\n bone.matrix.copy(bone.parent.matrixWorld).invert()\n bone.matrix.multiply(globalMatrix)\n } else {\n bone.matrix.copy(globalMatrix)\n }\n\n if (options.preserveHipPosition && name === options.hip) {\n bone.matrix.setPosition(pos.set(0, bone.position.y, 0))\n }\n\n bone.matrix.decompose(bone.position, bone.quaternion, bone.scale)\n\n bone.updateMatrixWorld()\n }\n\n if (options.preservePosition) {\n for (let i = 0; i < bones.length; ++i) {\n bone = bones[i]\n name = options.names[bone.name] || bone.name\n\n if (name !== options.hip) {\n bone.position.copy(bonesPosition[i])\n }\n }\n }\n\n if (options.preserveMatrix) {\n // restore matrix\n\n target.updateMatrixWorld(true)\n }\n}\n\nfunction retargetClip(target, source, clip, options = {}) {\n options.useFirstFramePosition = options.useFirstFramePosition !== undefined ? options.useFirstFramePosition : false\n options.fps = options.fps !== undefined ? options.fps : 30\n options.names = options.names || []\n\n if (!source.isObject3D) {\n source = getHelperFromSkeleton(source)\n }\n\n const numFrames = Math.round(clip.duration * (options.fps / 1000) * 1000),\n delta = 1 / options.fps,\n convertedTracks = [],\n mixer = new AnimationMixer(source),\n bones = getBones(target.skeleton),\n boneDatas = []\n let positionOffset, bone, boneTo, boneData, name\n\n mixer.clipAction(clip).play()\n mixer.update(0)\n\n source.updateMatrixWorld()\n\n for (let i = 0; i < numFrames; ++i) {\n const time = i * delta\n\n retarget(target, source, options)\n\n for (let j = 0; j < bones.length; ++j) {\n name = options.names[bones[j].name] || bones[j].name\n\n boneTo = getBoneByName(name, source.skeleton)\n\n if (boneTo) {\n bone = bones[j]\n boneData = boneDatas[j] = boneDatas[j] || { bone: bone }\n\n if (options.hip === name) {\n if (!boneData.pos) {\n boneData.pos = {\n times: new Float32Array(numFrames),\n values: new Float32Array(numFrames * 3),\n }\n }\n\n if (options.useFirstFramePosition) {\n if (i === 0) {\n positionOffset = bone.position.clone()\n }\n\n bone.position.sub(positionOffset)\n }\n\n boneData.pos.times[i] = time\n\n bone.position.toArray(boneData.pos.values, i * 3)\n }\n\n if (!boneData.quat) {\n boneData.quat = {\n times: new Float32Array(numFrames),\n values: new Float32Array(numFrames * 4),\n }\n }\n\n boneData.quat.times[i] = time\n\n bone.quaternion.toArray(boneData.quat.values, i * 4)\n }\n }\n\n mixer.update(delta)\n\n source.updateMatrixWorld()\n }\n\n for (let i = 0; i < boneDatas.length; ++i) {\n boneData = boneDatas[i]\n\n if (boneData) {\n if (boneData.pos) {\n convertedTracks.push(\n new VectorKeyframeTrack(\n '.bones[' + boneData.bone.name + '].position',\n boneData.pos.times,\n boneData.pos.values,\n ),\n )\n }\n\n convertedTracks.push(\n new QuaternionKeyframeTrack(\n '.bones[' + boneData.bone.name + '].quaternion',\n boneData.quat.times,\n boneData.quat.values,\n ),\n )\n }\n }\n\n mixer.uncacheAction(clip)\n\n return new AnimationClip(clip.name, -1, convertedTracks)\n}\n\nfunction clone(source) {\n const sourceLookup = new Map()\n const cloneLookup = new Map()\n\n const clone = source.clone()\n\n parallelTraverse(source, clone, function (sourceNode, clonedNode) {\n sourceLookup.set(clonedNode, sourceNode)\n cloneLookup.set(sourceNode, clonedNode)\n })\n\n clone.traverse(function (node) {\n if (!node.isSkinnedMesh) return\n\n const clonedMesh = node\n const sourceMesh = sourceLookup.get(node)\n const sourceBones = sourceMesh.skeleton.bones\n\n clonedMesh.skeleton = sourceMesh.skeleton.clone()\n clonedMesh.bindMatrix.copy(sourceMesh.bindMatrix)\n\n clonedMesh.skeleton.bones = sourceBones.map(function (bone) {\n return cloneLookup.get(bone)\n })\n\n clonedMesh.bind(clonedMesh.skeleton, clonedMesh.bindMatrix)\n })\n\n return clone\n}\n\n// internal helper\n\nfunction getBoneByName(name, skeleton) {\n for (let i = 0, bones = getBones(skeleton); i < bones.length; i++) {\n if (name === bones[i].name) return bones[i]\n }\n}\n\nfunction getBones(skeleton) {\n return Array.isArray(skeleton) ? skeleton : skeleton.bones\n}\n\nfunction getHelperFromSkeleton(skeleton) {\n const source = new SkeletonHelper(skeleton.bones[0])\n source.skeleton = skeleton\n\n return source\n}\n\nfunction parallelTraverse(a, b, callback) {\n callback(a, b)\n\n for (let i = 0; i < a.children.length; i++) {\n parallelTraverse(a.children[i], b.children[i], callback)\n }\n}\n\nexport const SkeletonUtils = { retarget, retargetClip, clone }\n"],"names":["Vector3","Quaternion","Matrix4","AnimationMixer","VectorKeyframeTrack","QuaternionKeyframeTrack","AnimationClip","clone","SkeletonHelper"],"mappings":"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"}