{"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":";;;AAWA,SAAS,SAAS,QAAQ,QAAQ,UAAU,CAAA,GAAI;AAC9C,QAAM,MAAM,IAAIA,cAAS,GACvB,OAAO,IAAIC,MAAAA,WAAY,GACvB,QAAQ,IAAID,MAAAA,QAAS,GACrB,iBAAiB,IAAIE,MAAAA,QAAS,GAC9B,iBAAiB,IAAIA,MAAAA,QAAS,GAC9B,eAAe,IAAIA,MAAAA,QAAS;AAE9B,UAAQ,iBAAiB,QAAQ,mBAAmB,SAAY,QAAQ,iBAAiB;AACzF,UAAQ,mBAAmB,QAAQ,qBAAqB,SAAY,QAAQ,mBAAmB;AAC/F,UAAQ,sBAAsB,QAAQ,wBAAwB,SAAY,QAAQ,sBAAsB;AACxG,UAAQ,kBAAkB,QAAQ,oBAAoB,SAAY,QAAQ,kBAAkB;AAC5F,UAAQ,MAAM,QAAQ,QAAQ,SAAY,QAAQ,MAAM;AACxD,UAAQ,QAAQ,QAAQ,SAAS,CAAE;AAEnC,QAAM,cAAc,OAAO,aAAa,OAAO,SAAS,QAAQ,SAAS,MAAM,GAC7E,QAAQ,OAAO,aAAa,OAAO,SAAS,QAAQ,SAAS,MAAM;AAErE,MAAI,WAAW,MAAM,MAAM,QAAQ;AAInC,MAAI,OAAO,YAAY;AACrB,WAAO,SAAS,KAAM;AAAA,EAC1B,OAAS;AACL,YAAQ,kBAAkB;AAC1B,YAAQ,iBAAiB;AAAA,EAC1B;AAED,MAAI,QAAQ,kBAAkB;AAC5B,oBAAgB,CAAE;AAElB,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,oBAAc,KAAK,MAAM,CAAC,EAAE,SAAS,OAAO;AAAA,IAC7C;AAAA,EACF;AAED,MAAI,QAAQ,gBAAgB;AAG1B,WAAO,kBAAmB;AAE1B,WAAO,YAAY,SAAU;AAI7B,aAAS,IAAI,GAAG,IAAI,OAAO,SAAS,QAAQ,EAAE,GAAG;AAC/C,aAAO,SAAS,CAAC,EAAE,kBAAkB,IAAI;AAAA,IAC1C;AAAA,EACF;AAED,MAAI,QAAQ,SAAS;AACnB,gBAAY,CAAE;AAEd,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,EAAE,GAAG;AACrC,aAAO,MAAM,CAAC;AACd,aAAO,QAAQ,MAAM,KAAK,IAAI,KAAK,KAAK;AAExC,UAAI,QAAQ,QAAQ,IAAI,GAAG;AACzB,aAAK,OAAO,SAAS,QAAQ,QAAQ,IAAI,CAAC;AAE1C,aAAK,OAAO,UAAU,KAAK,UAAU,KAAK,YAAY,KAAK,KAAK;AAEhE,aAAK,kBAAmB;AAAA,MACzB;AAED,gBAAU,KAAK,KAAK,YAAY,MAAK,CAAE;AAAA,IACxC;AAAA,EACF;AAED,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,EAAE,GAAG;AACrC,WAAO,MAAM,CAAC;AACd,WAAO,QAAQ,MAAM,KAAK,IAAI,KAAK,KAAK;AAExC,aAAS,cAAc,MAAM,WAAW;AAExC,iBAAa,KAAK,KAAK,WAAW;AAElC,QAAI,QAAQ;AACV,aAAO,kBAAmB;AAE1B,UAAI,QAAQ,iBAAiB;AAC3B,uBAAe,KAAK,OAAO,WAAW;AAAA,MAC9C,OAAa;AACL,uBAAe,KAAK,OAAO,WAAW,EAAE,OAAQ;AAChD,uBAAe,SAAS,OAAO,WAAW;AAAA,MAC3C;AAID,YAAM,mBAAmB,cAAc;AACvC,qBAAe,MAAM,MAAM,IAAI,IAAI,MAAM,GAAG,IAAI,MAAM,GAAG,IAAI,MAAM,CAAC,CAAC;AAIrE,mBAAa,2BAA2B,KAAK,sBAAsB,cAAc,CAAC;AAElF,UAAI,OAAO,YAAY;AACrB,cAAM,YAAY,MAAM,QAAQ,IAAI,GAClC,cAAc,YACV,UAAU,SAAS,IACnB,eAAe,KAAK,OAAO,SAAS,aAAa,SAAS,CAAC,EAAE,OAAQ;AAE3E,qBAAa,SAAS,WAAW;AAAA,MAClC;AAED,mBAAa,aAAa,cAAc;AAAA,IACzC;AAED,QAAI,KAAK,UAAU,KAAK,OAAO,QAAQ;AACrC,WAAK,OAAO,KAAK,KAAK,OAAO,WAAW,EAAE,OAAQ;AAClD,WAAK,OAAO,SAAS,YAAY;AAAA,IACvC,OAAW;AACL,WAAK,OAAO,KAAK,YAAY;AAAA,IAC9B;AAED,QAAI,QAAQ,uBAAuB,SAAS,QAAQ,KAAK;AACvD,WAAK,OAAO,YAAY,IAAI,IAAI,GAAG,KAAK,SAAS,GAAG,CAAC,CAAC;AAAA,IACvD;AAED,SAAK,OAAO,UAAU,KAAK,UAAU,KAAK,YAAY,KAAK,KAAK;AAEhE,SAAK,kBAAmB;AAAA,EACzB;AAED,MAAI,QAAQ,kBAAkB;AAC5B,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,EAAE,GAAG;AACrC,aAAO,MAAM,CAAC;AACd,aAAO,QAAQ,MAAM,KAAK,IAAI,KAAK,KAAK;AAExC,UAAI,SAAS,QAAQ,KAAK;AACxB,aAAK,SAAS,KAAK,cAAc,CAAC,CAAC;AAAA,MACpC;AAAA,IACF;AAAA,EACF;AAED,MAAI,QAAQ,gBAAgB;AAG1B,WAAO,kBAAkB,IAAI;AAAA,EAC9B;AACH;AAEA,SAAS,aAAa,QAAQ,QAAQ,MAAM,UAAU,CAAA,GAAI;AACxD,UAAQ,wBAAwB,QAAQ,0BAA0B,SAAY,QAAQ,wBAAwB;AAC9G,UAAQ,MAAM,QAAQ,QAAQ,SAAY,QAAQ,MAAM;AACxD,UAAQ,QAAQ,QAAQ,SAAS,CAAE;AAEnC,MAAI,CAAC,OAAO,YAAY;AACtB,aAAS,sBAAsB,MAAM;AAAA,EACtC;AAED,QAAM,YAAY,KAAK,MAAM,KAAK,YAAY,QAAQ,MAAM,OAAQ,GAAI,GACtE,QAAQ,IAAI,QAAQ,KACpB,kBAAkB,CAAE,GACpB,QAAQ,IAAIC,MAAc,eAAC,MAAM,GACjC,QAAQ,SAAS,OAAO,QAAQ,GAChC,YAAY,CAAE;AAChB,MAAI,gBAAgB,MAAM,QAAQ,UAAU;AAE5C,QAAM,WAAW,IAAI,EAAE,KAAM;AAC7B,QAAM,OAAO,CAAC;AAEd,SAAO,kBAAmB;AAE1B,WAAS,IAAI,GAAG,IAAI,WAAW,EAAE,GAAG;AAClC,UAAM,OAAO,IAAI;AAEjB,aAAS,QAAQ,QAAQ,OAAO;AAEhC,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,EAAE,GAAG;AACrC,aAAO,QAAQ,MAAM,MAAM,CAAC,EAAE,IAAI,KAAK,MAAM,CAAC,EAAE;AAEhD,eAAS,cAAc,MAAM,OAAO,QAAQ;AAE5C,UAAI,QAAQ;AACV,eAAO,MAAM,CAAC;AACd,mBAAW,UAAU,CAAC,IAAI,UAAU,CAAC,KAAK,EAAE,KAAY;AAExD,YAAI,QAAQ,QAAQ,MAAM;AACxB,cAAI,CAAC,SAAS,KAAK;AACjB,qBAAS,MAAM;AAAA,cACb,OAAO,IAAI,aAAa,SAAS;AAAA,cACjC,QAAQ,IAAI,aAAa,YAAY,CAAC;AAAA,YACvC;AAAA,UACF;AAED,cAAI,QAAQ,uBAAuB;AACjC,gBAAI,MAAM,GAAG;AACX,+BAAiB,KAAK,SAAS,MAAO;AAAA,YACvC;AAED,iBAAK,SAAS,IAAI,cAAc;AAAA,UACjC;AAED,mBAAS,IAAI,MAAM,CAAC,IAAI;AAExB,eAAK,SAAS,QAAQ,SAAS,IAAI,QAAQ,IAAI,CAAC;AAAA,QACjD;AAED,YAAI,CAAC,SAAS,MAAM;AAClB,mBAAS,OAAO;AAAA,YACd,OAAO,IAAI,aAAa,SAAS;AAAA,YACjC,QAAQ,IAAI,aAAa,YAAY,CAAC;AAAA,UACvC;AAAA,QACF;AAED,iBAAS,KAAK,MAAM,CAAC,IAAI;AAEzB,aAAK,WAAW,QAAQ,SAAS,KAAK,QAAQ,IAAI,CAAC;AAAA,MACpD;AAAA,IACF;AAED,UAAM,OAAO,KAAK;AAElB,WAAO,kBAAmB;AAAA,EAC3B;AAED,WAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,EAAE,GAAG;AACzC,eAAW,UAAU,CAAC;AAEtB,QAAI,UAAU;AACZ,UAAI,SAAS,KAAK;AAChB,wBAAgB;AAAA,UACd,IAAIC,MAAmB;AAAA,YACrB,YAAY,SAAS,KAAK,OAAO;AAAA,YACjC,SAAS,IAAI;AAAA,YACb,SAAS,IAAI;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAED,sBAAgB;AAAA,QACd,IAAIC,MAAuB;AAAA,UACzB,YAAY,SAAS,KAAK,OAAO;AAAA,UACjC,SAAS,KAAK;AAAA,UACd,SAAS,KAAK;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAED,QAAM,cAAc,IAAI;AAExB,SAAO,IAAIC,MAAa,cAAC,KAAK,MAAM,IAAI,eAAe;AACzD;AAEA,SAAS,MAAM,QAAQ;AACrB,QAAM,eAAe,oBAAI,IAAK;AAC9B,QAAM,cAAc,oBAAI,IAAK;AAE7B,QAAMC,SAAQ,OAAO,MAAO;AAE5B,mBAAiB,QAAQA,QAAO,SAAU,YAAY,YAAY;AAChE,iBAAa,IAAI,YAAY,UAAU;AACvC,gBAAY,IAAI,YAAY,UAAU;AAAA,EAC1C,CAAG;AAED,EAAAA,OAAM,SAAS,SAAU,MAAM;AAC7B,QAAI,CAAC,KAAK;AAAe;AAEzB,UAAM,aAAa;AACnB,UAAM,aAAa,aAAa,IAAI,IAAI;AACxC,UAAM,cAAc,WAAW,SAAS;AAExC,eAAW,WAAW,WAAW,SAAS,MAAO;AACjD,eAAW,WAAW,KAAK,WAAW,UAAU;AAEhD,eAAW,SAAS,QAAQ,YAAY,IAAI,SAAU,MAAM;AAC1D,aAAO,YAAY,IAAI,IAAI;AAAA,IACjC,CAAK;AAED,eAAW,KAAK,WAAW,UAAU,WAAW,UAAU;AAAA,EAC9D,CAAG;AAED,SAAOA;AACT;AAIA,SAAS,cAAc,MAAM,UAAU;AACrC,WAAS,IAAI,GAAG,QAAQ,SAAS,QAAQ,GAAG,IAAI,MAAM,QAAQ,KAAK;AACjE,QAAI,SAAS,MAAM,CAAC,EAAE;AAAM,aAAO,MAAM,CAAC;AAAA,EAC3C;AACH;AAEA,SAAS,SAAS,UAAU;AAC1B,SAAO,MAAM,QAAQ,QAAQ,IAAI,WAAW,SAAS;AACvD;AAEA,SAAS,sBAAsB,UAAU;AACvC,QAAM,SAAS,IAAIC,MAAc,eAAC,SAAS,MAAM,CAAC,CAAC;AACnD,SAAO,WAAW;AAElB,SAAO;AACT;AAEA,SAAS,iBAAiB,GAAG,GAAG,UAAU;AACxC,WAAS,GAAG,CAAC;AAEb,WAAS,IAAI,GAAG,IAAI,EAAE,SAAS,QAAQ,KAAK;AAC1C,qBAAiB,EAAE,SAAS,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,QAAQ;AAAA,EACxD;AACH;AAEY,MAAC,gBAAgB,EAAE,UAAU,cAAc,MAAK;;"}