Rotate an already rotated child bone

Hello,

I have a character in T-pose with its skeleton, it’s a downloaded FBX file, I want to make the left arm to point in the direction of an existing point in world space.
I can see the axis of the left arm is rotated, using an AxesHelper. I have tried using the lookAt method in the left arm bone, I have tried creating a quaternion with the setFromUnitVectors and then using it with the slerp method in the left arm, without success.

I would be great some help.

Thanks.

Are you sure you are rotating the correct object?
Rotation works on joints just fine typically

Thanks for replaying.
Yes, it’s a model with skin mesh, bones, downloaded from mixamo. I tested some animations on it, in mixamo website. I can access the all bones from my scene. But I cannot rotate a child bone to make it point in the direction of point in the world space.

I think lookAt is in local space… so if you want to point a bone at a world space point, you have to transform the point into bone local space before the .lookAt…

Maybe something like:


let tmp = new THREE.Vector3()


tmp.copy(worldSpaceTargetPoint)
bone.worldToLocal( tmp )
bone.lookAt( tmp )

Thanks, I will try and I let you know the result.

For a better explanation of what I’m facing, look the model and the axis on each arm:
Screenshot 2023-12-01 170612
I would like to be able to make the arms pointing to any point in front of the character. it does not need to be both arms to the same point. The points will be given. For example, a point to the left-top corner for the left arm, like 45 degrees in x, y, z.

What we’re confused with is why you cant rotate anything. Have you tried just traversing all joints with a random rotation?
just to see if you are in fact missing something
Are you using .getObjectByName() ?

This bit of code will make a wreck of the model but it will prove things are rotateable.
If its true, you are not selecting correctly

mainObject.traverse( ( item ) => {
 if (item.isMesh) {
    console.log(item.name);
    item.rotation.set(Math.random()*Math.PI*2, Math.random()*Math.PI*2, Math.random()*Math.PI*2, )
 }

});

Its possible that the bone you are trying to rotate doesnt have any weights on it. It also may be a bone that is specific to mixamo. Also I think lookAt affects the head and tail of the bone at the same time, so you are likely getting bone roll only. First confirm that your bones have weighting on it by rotating the bones themselves. If you wish to try to point it somewhere, then you likely have to adjust the shoulder bone tail, meaning adjust the elbow bone head, meaning the next child bone that is currently in your picture. You can also try to setup an IK chain for the wrist, which includes the elbow and shoulder joint. Also the axis of the bones are a mismatch on your model.

Thanks, I think I’m selecting the bones properly, I have checked their names before, when I loaded the model the first time.
I made a test with this code:

const loader = new THREE.FBXLoader();
loader.load('girl.fbx',
  function (fbx) {
    currentFbx = fbx;
    scene.add(fbx);
    let leftArmBone;
    let rightArmBone;
    fbx.traverse((obj) => {
      if (obj.type === "Bone") {
        if(obj.name === "mixamorigLeftArm") {
          leftArmBone = obj;
          obj.add(new THREE.AxesHelper( 50 ));
        }
        else if (obj.name === "mixamorigRightArm") {
          rightArmBone = obj;
          obj.add(new THREE.AxesHelper( 50 ));
        }
        else if(obj.name === "mixamorigHips") {
          obj.position.y = 0;
        }
      }
    });

    leftArmBone.rotation.set(45*Math.PI/180, 45*Math.PI/180, 45*Math.PI/180);
    rightArmBone.rotation.set(45*Math.PI/180, 45*Math.PI/180, 45*Math.PI/180);
  },
  function (xhr) {
    console.log((xhr.loaded / xhr.total * 100) + '% loaded');
  },
  function (error) {
    console.log(error);
  }
);

and I get this:

Screenshot 2023-12-02 112136
Screenshot 2023-12-02 112155
Screenshot 2023-12-02 112213

I just added axis to those bones to see their orientations, they come like that in the model.

If I detached the bones by adding them to the scene, make the rotations and attached them back to theirs parents:

const loader = new THREE.FBXLoader();
loader.load('girl.fbx',
  function (fbx) {
    currentFbx = fbx;
    scene.add(fbx);
    let leftArmBone;
    let rightArmBone;
    fbx.traverse((obj) => {
      if (obj.type === "Bone") {
        if(obj.name === "mixamorigLeftArm") {
          leftArmBone = obj;
          obj.add(new THREE.AxesHelper( 50 ));
        }
        else if (obj.name === "mixamorigRightArm") {
          rightArmBone = obj;
          obj.add(new THREE.AxesHelper( 50 ));
        }
        else if(obj.name === "mixamorigHips") {
          obj.position.y = 0;
        }
      }
    });
    const leftArmParent = leftArmBone.parent;
    const rightArmParent = rightArmBone.parent;

    scene.add(leftArmParent);
    scene.add(rightArmParent);

    leftArmBone.rotation.set(45*Math.PI/180, 45*Math.PI/180, 45*Math.PI/180);
    rightArmBone.rotation.set(45*Math.PI/180, 45*Math.PI/180, 45*Math.PI/180);

    leftArmParent.add(leftArmBone);
    rightArmParent.add(rightArmBone);
  },
  function (xhr) {
    console.log((xhr.loaded / xhr.total * 100) + '% loaded');
  },
  function (error) {
    console.log(error);
  }
);

then, I get this:

Screenshot 2023-12-02 113144
Screenshot 2023-12-02 113204

Okay, so what exactly is that you want to know ? You’ve given so many vague issues.

As for the arms crossing on opposite directions, like i said before, the axis are not alligned on your model.

And as for the arms going into the stomach. Whats the point of reparenting your arm bones ? Those bones are already correctly parented, they are parented on what looks like the torso/spine bone, but with an offset. Since your model seems to be missing clavicle bones and you are reparenting those arm bones via code, threejs will fix your arm bone head to its parent bone head, which seems to be somewhere in the torsal area. So your leftArmParent and rightArmParent are actually the same parent bone, which is a torso/spine bone, if you really want to reparent those bones correctly you can add an offset to the arm bones. But whats the point, your arm bones are likely already correctly parented to begin with.

Thanks @Akroob.
The arms bones has a shoulder parent bone, each of them, left and right shoulder. and and a spine bone is the parent of both shoulder.
Yes, the axis are not aligned, but I don´t know if there is a way to align them. The orientation of those axis comes with the model.

Mmm, okay, so it comes with shoulder bones. Now that I look at your model closer the arms indeed get parented into the should bone head. But, what exactly is the ultimate question again ?

Thanks @Akroob,
I want to be able of rotating the arms to make them point in the direction of any given point of the scene, in world space, mainly in front of the model.
I know how to to that with objects direct children of the scene. But it’s diffent with children objects.