getSkeletonOffsets static method

dynamic getSkeletonOffsets(
  1. dynamic target,
  2. dynamic source, [
  3. dynamic options
])

Implementation

static getSkeletonOffsets(target, source, [options]) {
  options = options ?? {};

  var targetParentPos = Vector3(),
      targetPos = Vector3(),
      sourceParentPos = Vector3(),
      sourcePos = Vector3(),
      targetDir = Vector2(),
      sourceDir = Vector2();

  options.hip = options.hip ?? 'hip';
  options.names = options.names ?? {};

  if (!source.isObject3D) {
    source = getHelperFromSkeleton(source);
  }

  var nameKeys = options.names.keys,
      nameValues = options.names.values,
      sourceBones = source.isObject3D ? source.skeleton.bones : getBones(source),
      bones = target.isObject3D ? target.skeleton.bones : getBones(target),
      offsets = [];

  var bone, boneTo, name, i;

  target.skeleton.pose();

  for (i = 0; i < bones.length; ++i) {
    bone = bones[i];
    name = options.names[bone.name] || bone.name;

    boneTo = getBoneByName(name, sourceBones);

    if (boneTo && name != options.hip) {
      var boneParent = getNearestBone(bone.parent, nameKeys),
          boneToParent = getNearestBone(boneTo.parent, nameValues);

      boneParent.updateMatrixWorld();
      boneToParent.updateMatrixWorld();

      targetParentPos.setFromMatrixPosition(boneParent.matrixWorld);
      targetPos.setFromMatrixPosition(bone.matrixWorld);

      sourceParentPos.setFromMatrixPosition(boneToParent.matrixWorld);
      sourcePos.setFromMatrixPosition(boneTo.matrixWorld);

      targetDir
          .subVectors(Vector2(targetPos.x, targetPos.y), Vector2(targetParentPos.x, targetParentPos.y))
          .normalize();

      sourceDir
          .subVectors(Vector2(sourcePos.x, sourcePos.y), Vector2(sourceParentPos.x, sourceParentPos.y))
          .normalize();

      var laterialAngle = targetDir.angle() - sourceDir.angle();

      var offset = Matrix4().makeRotationFromEuler(Euler(0, 0, laterialAngle));

      bone.matrix.multiply(offset);

      bone.matrix.decompose(bone.position, bone.quaternion, bone.scale);

      bone.updateMatrixWorld();

      offsets[name] = offset;
    }
  }

  return offsets;
}