THREE.js Запекание позы скелета - преобразование позы A в позу T

Я создаю импортер DAZ и пытаюсь заставить экспорт A-позы по умолчанию работать с моей коллекцией анимаций T-позы. Вот что я делаю:

  1. Экспорт персонажа в DAZ с настройками по умолчанию и загрузка в Three.js
  2. Применение переопределений вращения костей, т.е. lShldrBend{x: -1, y: 0, z: 0.8}
  3. Запуск сценария выпечки, который работает аналогично STLExporter (код ниже)
  4. Теперь персонаж правильно выглядит в позе T, а все вращения равны 0,0,0. Это хорошо.

НО вот проблема(руки и их дети):

Детские кости измененной кости становятся все перепутанными. Что мне нужно сделать? Вот мой скелетный скрипт для выпечки (упрощено, нормали опущены)

      function bakeSkeleton ( target ) {
  var v1 = new Vector3();

  target.traverse( function ( object ) {
    if ( !object.isSkinnedMesh ) return;
    if ( object.geometry.isBufferGeometry !== true ) throw new Error( 'Only BufferGeometry supported.' );

    var positionAttribute = object.geometry.getAttribute( 'position' );

    for ( var j = 0; j < positionAttribute.count; j++ ) {
      object.boneTransform( j, v1 );
      positionAttribute.setXYZ( j, v1.x, v1.y, v1.z);
    }

    positionAttribute.needsUpdate = true;

     // commented out stuff is where I tried to apply rotation matrix to children's inverse matrices
    // const orgUninverse = new Matrix4();
    // const q1 = new Quaternion();
    // const mat = new Matrix4();
    // const inverse = new Matrix4();
    object.skeleton.bones.forEach((bone, i) => {
      // q1.copy(bone.quaternion)
      // mat.makeRotationFromQuaternion(q1)

      bone.rotation.set(0,0,0);
      // bone.updateMatrix();
      // bone.children.forEach(child => {
      //   const bid = object.skeleton.bones.indexOf(child)
      //   if (bid === -1) {
      //     console.log('bone not in skeleton', child.name)
      //     return
      //   }
      //   console.log('bone fond', child.name)
      //   orgUninverse.getInverse(object.skeleton.boneInverses[bid])
      //   orgUninverse.multiply(mat.makeRotationFromQuaternion(q1))
      //   object.skeleton.boneInverses[bid].getInverse(orgUninverse);
      // })
    })
  } );
}

Обновлять

Я обнаружил, что гораздо более простой способ изменить позу — применить заслуженные повороты (но перевернутые) и вызвать скелет.calculateInverses(). Поза применяется правильно, и все повороты равны 0,0,0, но снова во время анимации возникает та же проблема, что и на картинке.

0 ответов

Другие вопросы по тегам