Bake skeleton pose - converting A pose to T pose

I’m building a DAZ importer and trying to get default A pose exports to work with my T-pose animations.
Here’s what I’m doing:

  1. Importing character in A pose
  2. Applying bone rotation overrides i.e. lShoulderBend {x: 1, y: 0.2, z: 0.1 }
  3. Running baking script which works similarly to STLExporter (code below)
  4. Now the character looks correctly in T pose and rotations are all at 0,0,0

BUT here’s the problem(arms and their children):

Children bones of the changed bone become all messed up. What do I have to do? Here’s my bake skeleton script

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);
      // })
    })
  } );
}

Update:
Much easier way of changing the starting pose is applying deserved rotations(but inverted) and calling skeleton.calculateInverses(). The pose gets applied correctly and all rotations are 0,0,0 but again during animation the same problem occurs

It’s even stranger now.
Setting all bones’ rotations to 0,0,0 gets to the desired T-Pose (seems like it worked)

But calling skeleton.pose() sets the skeleton in the original A-Pose. Now this is getting interesting.

@rockclimber Were you ever able to get this working? I managed to set the rest pose like you did but the rotation values of the skeleton are still nonzero. This causes many adverse effects in my application

I can say from experience, that these problems are often reaaaally difficult to solve… and usually best solved in a modelling tool like Blender rather than hacking transforms in threejs.
If a model is authored from one pose, adapting it to a different one often required creating different bind matrices… or retargeting the animations themselves to work with the new rig.
Additionally different formats store bones differently… FBX sometimes uses a different axis along the length of the bones…
Sometimes the quaternions are in a different format… stored as WXYZ instead of XYZW.
There are sooo many things that can go wrong.

I’m not saying you can’t figure it out… but… I can say… I’ve only been successful at these things about 30% of the time… (and that is with >30 years of experience in 3d graphics and animation programming.)

vs. Using a tool like blender, where artists and modellers have to solve these problems a lot, and there are help threads and workflows that already exist to facilitate these kinds of transformations.

@Alfredo_Gonzalez it’s a complex problem but I have a solid solution which I could potentially license for a few $k. Besides pose changing it also supports skeletons merging, removing/merging bones which involves merging and reindexing weight attributes. This way half of runtime matrix computations can be avoided, face bones removed and for lower LOD, fingers and toes removed. It works on Daz 3D models exported to FBX in the default A pose. Recently experimented with adding also Genesis 9 support(new bone names, slightly different pose) and it worked on the deafult character, but haven’t tried with clothes yet. Can send me your FBX-exported character so I can see if my script works on it?

@manthrax That’s right it requires changing binding matrices, baking transforms into the geometry etc. The good part is, once it’s done and the character is in T-pose most standard animations like from mixamo work and look correct and there’s no need for animation retargeting. FBX-specific issues are solved in Three FBX loader pretty well so my solution comes in when in the first place a character is correctly loaded and looks good in its default pose.